python 多进程池、多线程池、协程池 实现笔记

进程:一个运行的程序(代码)就是一个进程,没有运行的代码叫程序,进程是系统资源分配的最小单位,进程拥有自己独立的内存空间,所有进程间数据不共享,开销大。

线程: cpu调度执行的最小单位,也叫执行路径,不能独立存在,依赖进程存在,一个进程至少有一个线程,叫主线程,而多个线程共享内存可以极大地提高了程序的运行效率。

协程: 是一种用户态的轻量级线程,协程的调度完全由用户控制,协程拥有自己的寄存器上下文和栈。协程调度时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操中栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快。

多进程:


from multiprocessing import Pool

import time
def test(i):
    print(i)
    time.sleep(1)

if  __name__ == "__main__":
    lists = [i for i in range(1,1000)]
    pool = Pool(processes=100)       #定义最大的进程数
    pool.map(test, lists)          #p必须是一个可迭代变量。
    pool.close()
    pool.join()

多线程


import time
from threading import Thread
from queue import Queue

def echo_client(q):
    print(f"---------- :{q}")
    time.sleep(1)

def echo_server(nworkers):
    # Launch the client workers
    q = Queue()
    for n in range(nworkers):
        t = Thread(target=echo_client, args=(q,))
        t.daemon = True
        t.start()

echo_server(128)

协程池


import uuid

import gevent
from gevent import monkey, pool
import time, random
import urllib.request

monkey.patch_all()

jpg_num = 0

def down_load_img(img_uel, img_name):
    global jpg_num
    jpg_num += 1
    print("正在下载第{}张".format(jpg_num))

    img = urllib.request.urlopen(img_uel)  # 设置网络连接
    img_content = img.read()  # 读取网址信息
    # 设置一个新的文件并将信息写入
    with open(r"%s" % img_name, "wb") as f1:
        f1.write(img_content)
        time.sleep(random.random())
    time.sleep(2)

def main():
    p = pool.Pool(50)  # 创建协程池
    url = 'https://www.google.com/imgres?imgurl=https%3A%2F%2Fpic2.cwuzx.com%2Fe390d4d07e852ebc2de3bbbbfd08bb31db705194-800.jpg&imgrefurl=https%3A%2F%2Fwww.cwuzx.com%2Fimage%2F24.html&tbnid=VTjovih6x09TsM&vet=12ahUKEwi4n_fHm5nqAhXwzIsBHWacBQ0QMygFegUIARCrAQ..i&docid=HC2ZQVVBJ4T2qM&w=650&h=432&q=%E7%8C%AB%E5%9B%BE%E7%89%87&ved=2ahUKEwi4n_fHm5nqAhXwzIsBHWacBQ0QMygFegUIARCrAQ'
    ret_list = [url for i in range(0,1000)]

    # 重置列表
    num = 0
    my_list = []

    t_start = time.time()  # 设置开始时间
    for img_url in ret_list:
        my_list.append(p.spawn(down_load_img, img_url, "%s.jpg" % str(uuid.uuid4())))
        if num == 100:  # 设置想要的下载文件数量
            break
        num += 1

    gevent.joinall(my_list)  # 添加任务到协程池
    t_stop = time.time()  # 设置结束时间
    print("下载文件一共用了:%.2f秒" % (t_stop - t_start))  # 计时

if __name__ == '__main__':
    main()

猜你喜欢

转载自blog.51cto.com/mapengfei/2506740