123 Python程序中的线程操作-协程
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了123 Python程序中的线程操作-协程,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3244字,纯文字阅读大概需要5分钟。
内容图文
![123 Python程序中的线程操作-协程](/upload/InfoBanner/zyjiaocheng/713/0005d3be6eb94d4b8ecd5dad9234b002.jpg)
目录
一、什么是协程
协程: 就是单线程下实现并发
协程概念本质是程序员抽象出来的,是人为的控制通过程序的IO去进行切换任务的执行
并发:任务切换+保存状态
二、为什么要有协程
自己控制切换要比操作系统切换快的多.降低了单个线程的io堵塞时间,也就是实现了单线程下效率最高.
三、协程的优缺点
优点:
自己控制切换要比操作系统切换快的多
缺点:
- 需要自己要检测所有的io,但凡有一个阻塞整体都跟着阻塞.
- 无法利用多核优势.
四、如何实现协程
其实协程的本质就是在单线程下实现并发,也就是通过生成器yield
和next
进行迭代生成器,实现切换任务和保存任务。
在Python中我们需要使用gevnet模块来实现协程
五、Gevent模块
Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet,它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。
5.1 模块的安装
安装:`pip3 install gevent
5.2 用法介绍
g1=gevent.spawn(func,1,,2,3,x=4,y=5)
:创建一个协程对象g1,spawn括号内第一个参数是函数名,如eat,后面可以有多个参数,可以是位置实参或关键字实参,都是传给函数eat的
g2=gevent.spawn(func2)
g1.join()
:等待g1结束
g2.join()
:等待g2结束
上述两步合作一步:gevent.joinall([g1,g2])
g1.value
:拿到func1的返回值
5.3 代码实例
通过from gevent import monkey;
monkey.patch_all()去补丁,捕获所以IO
from gevent import monkey;monkey.patch_all()
必须放到被打补丁者的前面,如time,socket模块之前。
import time
from gevent import monkey;monkey.patch_all()
'''打了一个补丁,它可以实现捕获非gevent的所有io'''
import gevent
def eat():
print('eat 1')
time.sleep(2)
# gevent.sleep(2) # 可以这样单独捕捉阻塞,但是太麻烦,所以直接打补丁,捕捉运行期间的全部IO
print('eat 2')
def play():
print('play 1')
# 疯狂的计算呢没有io
time.sleep(3)
# gevent.sleep(3) # 可以这样单独捕捉阻塞,但是太麻烦,所以直接打补丁,捕捉运行期间的全部IO
print('play 2')
'''
gevent实现协程的模块,它可以捕获单线程中的io并去切换任务
'''
if __name__ == '__main__':
# 把本该串行的代码通过协程完成单线程并行
start = time.time()
g1 = gevent.spawn(eat) # 创建一个协程对象
g2 = gevent.spawn(play)
# g1.join() # 等待回收协程对象
# g2.join()
gevent.joinall([g1,g2]) # 把上面两步并一步
end = time.time()
print(end-start)
六、gevent之应用
通过gevent实现单线程下的socket并发
注意:from gevent import monkey;monkey.patch_all()一定要放到导入socket模块之前,否则gevent无法识别socket的阻塞。
服务器
import socket
from gevent import monkey; monkey.patch_all() # 打补丁
import gevent
'''
基于协程的socket通讯
协程:单线程下实现并发
'''
def connec_interface(conn,addr):
while 1:
try:
data = conn.recv(1024)
if not data:
break
print(f"来自{addr}的消息:",data.decode("utf8"))
data = input(f"与{addr}聊天")
conn.send(data.encode("utf8"))
except:
break
if __name__ == '__main__':
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(("127.0.0.1",8080))
server.listen(5)
while 1:
print("等待连接。。。")
conn,addr = server.accept()
print("连接成功")
gevent.spawn(connec_interface, conn, addr) # 创建一个协程对象
客户端
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(("127.0.0.1",8080))
while 1:
msg = input("请输入内容")
client.send(msg.encode("utf8"))
data = client.recv(1024)
if not data:
break
print(data.decode("utf8"))
内容总结
以上是互联网集市为您收集整理的123 Python程序中的线程操作-协程全部内容,希望文章能够帮你解决123 Python程序中的线程操作-协程所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。