一 gevent模块

  1. 安装
  2. pip3 install gevent

Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。

  1. #用法
  2. g1=gevent.spawn(func,1,,2,3,x=4,y=5)创建一个协程对象g1spawn括号内第一个参数是函数名,如eat,后面可以有多个参数,可以是位置实参或关键字实参,都是传给函数eat
  3. g2=gevent.spawn(func2)
  4. g1.join() #等待g1结束
  5. g2.join() #等待g2结束
  6. #或者上述两步合作一步:gevent.joinall([g1,g2])
  7. g1.value#拿到func1的返回值

遇到IO阻塞时会自动切换任务

  1. import gevent
  2. def eat(name):
  3. print('%s eat 1' %name)
  4. gevent.sleep(2)
  5. print('%s eat 2' %name)
  6. def play(name):
  7. print('%s play 1' %name)
  8. gevent.sleep(1)
  9. print('%s play 2' %name)
  10. g1=gevent.spawn(eat,'egon')
  11. g2=gevent.spawn(play,name='egon')
  12. g1.join()
  13. g2.join()
  14. #或者gevent.joinall([g1,g2])
  15. print('主')

上例gevent.sleep(2)模拟的是gevent可以识别的io阻塞,

而time.sleep(2)或其他的阻塞,gevent是不能直接识别的需要用下面一行代码,打补丁,就可以识别了

from gevent import monkey;monkey.patch_all()必须放到被打补丁者的前面,如time,socket模块之前

或者我们干脆记忆成:要用gevent,需要将from gevent import monkey;monkey.patch_all()放到文件的开头

  1. from gevent import monkey;monkey.patch_all()
  2. import gevent
  3. import time
  4. def eat():
  5. print('eat food 1')
  6. time.sleep(2)
  7. print('eat food 2')
  8. def play():
  9. print('play 1')
  10. time.sleep(1)
  11. print('play 2')
  12. g1=gevent.spawn(eat)
  13. g2=gevent.spawn(play_phone)
  14. gevent.joinall([g1,g2])
  15. print('主')

我们可以用threading.current_thread().getName()来查看每个g1和g2,查看的结果为DummyThread-n,即假线程

二 练习

通过gevent实现单线程下的socket并发(from gevent import monkey;monkey.patch_all()一定要放到导入socket模块之前,否则gevent无法识别socket的阻塞)

服务端

  1. from gevent import monkey;monkey.patch_all()
  2. from socket import *
  3. import gevent
  4. #如果不想用money.patch_all()打补丁,可以用gevent自带的socket
  5. # from gevent import socket
  6. # s=socket.socket()
  7. def server(server_ip,port):
  8. s=socket(AF_INET,SOCK_STREAM)
  9. s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
  10. s.bind((server_ip,port))
  11. s.listen(5)
  12. while True:
  13. conn,addr=s.accept()
  14. gevent.spawn(talk,conn,addr)
  15. def talk(conn,addr):
  16. try:
  17. while True:
  18. res=conn.recv(1024)
  19. print('client %s:%s msg: %s' %(addr[0],addr[1],res))
  20. conn.send(res.upper())
  21. except Exception as e:
  22. print(e)
  23. finally:
  24. conn.close()
  25. if __name__ == '__main__':
  26. server('127.0.0.1',8080)

多线程并发多个客户端

  1. from threading import Thread
  2. from socket import *
  3. import threading
  4. def client(server_ip,port):
  5. c=socket(AF_INET,SOCK_STREAM) #套接字对象一定要加到函数内,即局部名称空间内,放在函数外则被所有线程共享,则大家公用一个套接字对象,那么客户端端口永远一样了
  6. c.connect((server_ip,port))
  7. count=0
  8. while True:
  9. c.send(('%s say hello %s' %(threading.current_thread().getName(),count)).encode('utf-8'))
  10. msg=c.recv(1024)
  11. print(msg.decode('utf-8'))
  12. count+=1
  13. if __name__ == '__main__':
  14. for i in range(500):
  15. t=Thread(target=client,args=('127.0.0.1',8080))
  16. t.start()

协程《三》gevent模块的更多相关文章

  1. 单线程实现并发——协程,gevent模块

    一 并发的本质 1 切换 2 保存状态 二 协程的概念 协程,又称微线程,纤程.英文名Coroutine.单线程下实现并发,用户从应用程序级别控制单线程下任务的切换,注意一定是遇到I/O才切. 协程的 ...

  2. Python程序中的协程操作-gevent模块

    目录 一.安装 二.Gevent模块介绍 2.1 用法介绍 2.2 例:遇到io主动切换 2.3 查看threading.current_thread().getName() 三.Gevent之同步与 ...

  3. GIL解释器,协程,gevent模块

    GIL解释器锁 在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势 首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CP ...

  4. day 34 线程队列 线程池 协程 Greenlet \Gevent 模块

    1 线程的其他方法 threading.current_thread().getName()    查询当前线程对象的名字 threading.current_thread().ident      ...

  5. python并发编程之asyncio协程(三)

    协程实现了在单线程下的并发,每个协程共享线程的几乎所有的资源,除了协程自己私有的上下文栈:协程的切换属于程序级别的切换,对于操作系统来说是无感知的,因此切换速度更快.开销更小.效率更高,在有多IO操作 ...

  6. 【python】-- 协程介绍及基本示例、协程遇到IO操作自动切换、协程(gevent)并发爬网页

    协程介绍及基本示例 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是协程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他 ...

  7. 协程,greenlet原生协程库, gevent库

    协程简介 协程(coroutine),又称为微线程,纤程,是一种用户级的轻量级线程.协程拥有自己的寄存器上下文和栈. 协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来时,恢复之前保存的上下文 ...

  8. 并发编程(六)——进程/线程池、协程、gevent第三方库

    进程/线程池.协程.gevent第三方库 一.进程/线程池 1.进程池 (1)什么是进程池 如果需要创建的子进程数量不大,可以直接利用multiprocess中的Process来创建.但是当需要创建上 ...

  9. python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用

    python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用 一丶单线程+多任务的异步协程 特殊函数 # 如果一个函数的定义被async修饰后,则该函数就是一个特殊的函数 async ...

  10. python 全栈开发,Day43(引子,协程介绍,Greenlet模块,Gevent模块,Gevent之同步与异步)

    昨日内容回顾 I/O模型,面试会问到I/O操作,不占用CPU.它内部有一个专门的处理I/O模块.print和写log 属于I/O操作,它不占用CPU 线程GIL保证一个进程中的多个线程在同一时刻只有一 ...

随机推荐

  1. linux c++ rabbitMq Demo

    1.在vs上实现远程调试Linux c++程序:https://www.jianshu.com/p/8b51a795cb92. 2.调试需要c++11,升级redhat上的gcc版本,虚拟机gcc版本 ...

  2. BugkuCTF 逆向

    Easy_vb 下载文件,打开 用 IDA 或 OD 打开 在中间部分发现 flag 把 MCTF 改成 flag,就是正确的 flag 了 Easy_Re 下载附件,打开

  3. 南京邮电大学网络攻防平台WEB题

    平台地址:http://ctf.nuptsast.com/ 签到题: 右键查看源代码,得到flag md5 collision: 传入的a的md5值要为0e开头的,但不能是QNKCDZO,百度一个0e ...

  4. Android 4 学习(14):Internet Resources

    参考<Professional Android 4 Development> 使用Internet资源 打开URI String myFeed = getString(R.string.m ...

  5. 用sysbench压测MySQL,通过orzdba监控MySQL

    1.1 安装sysbench wget https://codeload.github.com/akopytov/sysbench/zip/0.5 unzip 0.5 cd sysbench-0.5/ ...

  6. Stars(树状数组单点更新)

    Astronomers often examine star maps where stars are represented by points on a plane and each star h ...

  7. 15-EasyNetQ之对延迟消息插件的支持

    RabbitMQ延迟消息插件仍然在实验阶段.你使用这个功能要自担风险. RabbitMQ延迟消息插件为RabbitMQ增加了新的交换机类型,允许延时消息投递. EasyNetQ为交换机通过定义一种新的 ...

  8. 为Vmware里安装的CentOS7.5设置静态IP

    [引言]为测试搭建大数据集群环境,采用在Vmware里安装了几台CentOS7.5的虚拟机,在测试过程中,出现启动虚拟机后,虚拟机的IP地址会变,不方便测试集群,所以需要设置静态IP,在此,记录我的设 ...

  9. OpenCV---resize

    转自http://www.cnblogs.com/korbin/p/5612427.html 在图像处理过程中,有时需要把图像调整到同样大小,便于处理,这时需要用到图像resize() 原函数void ...

  10. hook NtQueryDirectoryFile实现文件隐藏

    一.NtQueryDirectoryFile函数功能(NT系列函数) NtQueryDirectoryFile函数:在一个给定的文件句柄,该函数返回该文件句柄指定目录下的不同文件的各种信息. 根据传入 ...