并发编程—协程

协程总结

原理+特点

  • 协程本质就是线程,指在一条线程上来回切换以规避I/O操作
  • 特点:数据共享,数据安全,不能利用多核,基于用户层面,开启/关闭花销时间比线程更少
  • 但是需要用户自己设置所以只有当用户能明显感知的I/O操作才能被用户自己设置线程,而线程是自动感知系统的I/O操作

优点

  • 可以减轻操作系统的压力,提高效率
  • 可以给线程多设置几条协程,给线程造成一种很忙的样子,这样系统会多分配些时间片给线程,从而提高代码的执行效率

开启模块

  • gevent模块
    • 基于greenlet(C语言底层模块)完成切换+自动规避I/O功能
  • asyncio模块
    • 基于python底层语法(yeild等)完成切换+自动规避I/O功能

gevent模块

from gevent import monkey  
monkey.patch_all()			#用来识别所有的I/O操作
import time
import gevent
def func():					#带I/O操作的内容写在函数中,通过提交func交给gevent
    print('start func')
    time.sleep(1)			#设置I/O操作
    print('end func')

g1=gevent.spawn(func)		#开启协程
g2=gevent.spawn(func)
g3=gevent.spawn(func)
g1.join()
g2.join()
g3.join()
# gevent.joinall([g1,g2,g3])

asyncio模块

import asyncio
import time

async def func(name):   
	# await关键字必须写在一个async函数里
    print('start',name)
    await asyncio.sleep(1)
    #await后面必须接可能会发生阻塞的方法
    print('end')

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait([func('团团'),func('圆圆')]))  #通过asyncio.await方法设置多个协程同时进行
# loop.run_until_complete(func('团团'))
# loop.run_until_complete(func('圆圆'))

进程/线程/协程比较

进程:数据隔离、数据不安全、可以使用多核、基于操作系统级别、开启/关闭花销时间大
线程:数据共享、数据不安全、不可以使用多核、基于操作系统级别、开启/关闭花销比进程小几百倍,线程可以系统自动规避I/O操作
协程:数据共享、数据不安全、不可以使用多核、基于用户级别、开启/关闭花销比线程更小,协程只能用户手动规避可以看得见的I/O操作

对于一个8核的cpu而言,开多少进程、线程、协程比较好?
进程数量:CPU数*1<进程数<CPU数*2			推荐开进程数量为CPU数量+1
线程数量:CPU数*5>=线程数
协程数量:500>=协程数
所以一个8核的cpu最多可开的并发数为(8*2)*(8*5)*500=320000,不推荐开这么多
原文地址:https://www.cnblogs.com/Programmatic-yuan/p/13254502.html