1. 协程是啥
线程和进程的操作是由程序触发系统接口,最后的执行者是系统,它本质上是操作系统提供的功能。而协程的操作则是程序员指定的,在python中通过yield,人为的实现并发处理。
协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时。协程,则只使用一个线程,分解一个线程成为多个“微线程”,在一个线程中规定某个代码块的执行顺序。
2. 计算密集型和IO密集型
计算密集型-->例如for循环里嵌套10层for循环-->占大量的cpu资源-->解决方案-->使用多进程不能用多线程(多线程中有个全局锁GIL)
IO密集型->需要网络功能,大量的事件等待网络数据的到来-->多线程、协成
3. 协程的好处
把一个IO操作 写成一个协程。当触发IO操作的时候就自动让出CPU给其他协程。要知道协程的切换很轻的。 协程通过这种对异步IO的封装 既保留了性能也保证了代码的容易编写和可读性。在高IO密集型的程序下很好。但是高CPU密集型的程序下没啥好处。
4、协程-gevent-自动切换
在python3中安装greenlet
sudo pip3 install python3-pip
gevent里面把socket重新封装了,用的时候就用gevent里面的monkey patch指的是在运行时动态替换,一般是在startup的时候,
用过gevent就会知道,会在最开头的地方gevent.monkey.patch_all(); 把标准库中的thread/socket等给替换掉.这样我们在后面使用socket
的时候可以跟平常一样使用,无需修改任何代码,但是它变成非阻塞的了.
import sys
import time
import gevent
from gevent import socket,monkey
monkey.patch_all()
def handle_request(conn):
while True:
data = conn.recv(1024)
if not data:
conn.close()
break
print("recv:", data)
conn.send(data)
def server(port):
s = socket.socket()
s.bind(('', port))
s.listen(5)
while True:
newSocket, addr = s.accept()
gevent.spawn(handle_request, newSocket)
if __name__ == '__main__':
server(7777)