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