深入了解python中的协程函数
本篇文章给大家分享的内容是深入了解python中的协程函数 ,有着一定的参考价值,有需要的朋友可以参考一下
概念:
根据维基百科给出的定义,“协程 是为非抢占式多任务产生子程序的计算机程序组件,协程允许不同入口点在不同位置暂停或开始执行程序”。从技术的角度来说,“协程就是你可以暂停执行的函数”。如果你把它理解成“就像生成器一样”,那么你就想对了。
协程,又称为微线程,看上去像是子程序,但是它和子程序又不太一样,它在执行的过程中,可以在中断当前的子程序后去执行别的子程序,再返回来执行之前的子程序,但是它的相关信息还是之前的。
协程不同于线程,线程是抢占式的调度,而协程是协同式的调度,协程需要自己做调度。
子程序调用总是一个入口,一次返回,调用顺序是明确的。而协程的调用和子程序不同。协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。
协程的优点:
协程优势是极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。用来执行协程多任务非常合适。
协程没有线程的安全问题。一个进程可以同时存在多个协程,但是只有一个协程是激活的,而且协程的激活和休眠又是程序员通过编程来控制,而不是操作系统控制的。
生成器实现协程原理
示例:
def func(n): index=0 if index<=n: c=yield 1 print("task------{}".format(c)) index+=1f=func(3) n=next(f) print(n)try: n=f.send(5)#程序就直接结束了 print("n是{}".format(n))except StopIteration as e: pass
输出打印:1task------5
解释说明:
很明显func是一个生成器,send方法有一个参数,该参数指定的是上一次被挂起的yield语句的返回值。
send需要做异常处理。
总的来说,send方法和next方法唯一的区别是在执行send方法会首先把上一次挂起的yield语句的返回值通过参数设定,从而实现与生成器方法的交互。但是需要注意,在一个生成器对象没有执行next方法之前,由于没有yield语句被挂起,所以执行send方法会报错。
send方法的参数为None时,它与next方法完全等价。
生成器实现生产者和消费者模式:
def cunsumer(): while True: n=yield 3 if not n: return print('cunsumer{}'.format(n))def product(c): c.send(None) n=0 while n<5: n=n+1 r=c.send(n) print("product{}".format(r)) c.close() c=cunsumer() product(c)
打印: cunsumer1 product3 cunsumer2 product3 cunsumer3 product3 cunsumer4 product3 cunsumer5 product3
解释说明:
在生产者里先执行了 c.send(None),目的是先让消费者挂起,再用send传值,第一次传1,消费者那里打印1,生产者打印r是消费者yield后面的值。
greenlet 的引入
虽然CPython(标准Python)能够通过生成器来实现协程,但使用起来还并不是很方便。
与此同时,Python的一个衍生版 Stackless Python实现了原生的协程,它更利于使用。
于是,大家开始将 Stackless 中关于协程的代码 单独拿出来做成了CPython的扩展包。
这就是 greenlet 的由来,因此 greenlet 是底层实现了原生协程的 C扩展库。
代码示意:
from greenlet import greenletimport randomimport timedef Producer(): while True: item = random.randint(0,10) print("生产了{}".format(item)) c.switch(item)#切换到消费者,并将item传入消费者 time.sleep(1)def consumer(): print('我先执行') #p.switch() while True: item = p.switch()#切换到生产者,并且等待生产者传入item print('消费了{}'.format(item)) c = greenlet(consumer)#将一个普通函数变成一个协程p = greenlet(Producer) c.switch()#让消费者先进入暂停状态(只有恢复了才能接收数据)
greenlet 的价值:
高性能的原生协程
语义更加明确的显式切换
直接将函数包装成协程,保持原有代码风格
gevent协程
虽然,我们有了 基于 epoll 的回调式编程模式,但是却难以使用。
即使我们可以通过配合 生成器协程 进行复杂的封装,以简化编程难度。
但是仍然有一个大的问题: 封装难度大,现有代码几乎完全要重写
gevent,通过封装了 libev(基于epoll) 和 greenlet 两个库。
帮我们做好封装,允许我们以类似于线程的方式使用协程。
以至于我们几乎不用重写原来的代码就能充分利用 epoll 和 协程 威力。
代码示意:
from gevent import monkey;monkey.patch_all()#会把python标准库当中一些阻塞操作变成非阻塞import geventdef test1(): print("11") gevent.sleep(4)#模拟爬虫请求阻塞 print("33")def test2(): print("22") gevent.sleep(4) print("44") gevent.joinall([gevent.spawn(test1),gevent.spawn(test2)])#joinall 阻塞当前协程,执行给定的greenlet#spawn 启动协程,参数就是函数的名字
gevent 的价值:
遇到阻塞就切换到另一个协程继续执行 !
使用基于 epoll 的 libev 来避开阻塞。
使用基于 gevent 的 高效协程 来切换执行。
只在遇到阻塞的时候切换,没有轮需的开销,也没有线程的开销。
gevent实现并发服务器
from gevent import monkey;monkey.patch_all() #建议放在首行,会把python标准库当中一些阻塞操作变成非阻塞import geventimport socket server=socket.socket() server.bind(('',6666)) server.listen(5) print("开始监听")def readable(con,addr): print("客户端{}接入".format(addr)) while True: data=con.recv(1024) if data: print(data) else: con.close() breakwhile True: con,addr=server.accept() gevent.spawn(readable,con,addr)#将readable函数变为协程,并且把con和addr传入其中。
gevent 协程通信
gevent也有自己的队列。使用方式和进线程基本一样。
基于gevent和队列的生产者和消费者模式
from gevent import monkey;monkey.patch_all()import geventfrom gevent.queue import Queueimport randomdef producter(queue): while True: item=random.randint(0,99) print('生产了{}'.format(item)) queue.put(item) gevent.sleep(1)def comuser(queue): while True: item=queue.get() print('消费了{}'.format(item)) queue=Queue() p=gevent.spawn(producter,queue) c=gevent.spawn(comuser,queue) gevent.joinall([p,c])
打印: 生产了33消费了33生产了95消费了95生产了92消费了92...
相关推荐:
Atas ialah kandungan terperinci 深入了解python中的协程函数. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Halaman H5 perlu dikekalkan secara berterusan, kerana faktor -faktor seperti kelemahan kod, keserasian pelayar, pengoptimuman prestasi, kemas kini keselamatan dan peningkatan pengalaman pengguna. Kaedah penyelenggaraan yang berkesan termasuk mewujudkan sistem ujian lengkap, menggunakan alat kawalan versi, kerap memantau prestasi halaman, mengumpul maklum balas pengguna dan merumuskan pelan penyelenggaraan.

PS "Memuatkan" Masalah disebabkan oleh akses sumber atau masalah pemprosesan: Kelajuan bacaan cakera keras adalah perlahan atau buruk: Gunakan CrystaldiskInfo untuk memeriksa kesihatan cakera keras dan menggantikan cakera keras yang bermasalah. Memori yang tidak mencukupi: Meningkatkan memori untuk memenuhi keperluan PS untuk imej resolusi tinggi dan pemprosesan lapisan kompleks. Pemandu kad grafik sudah lapuk atau rosak: Kemas kini pemandu untuk mengoptimumkan komunikasi antara PS dan kad grafik. Laluan fail terlalu panjang atau nama fail mempunyai aksara khas: Gunakan laluan pendek dan elakkan aksara khas. Masalah PS sendiri: Pasang semula atau membaiki pemasang PS.

Bagaimana untuk mendapatkan data dinamik 58.com halaman kerja semasa merangkak? Semasa merangkak halaman kerja 58.com menggunakan alat crawler, anda mungkin menghadapi ...

Penjelasan terperinci mengenai kemahiran kod JavaScript semasa menulis kod JavaScript, kita sering menemui garis kod yang terlalu panjang, yang bukan sahaja mempengaruhi kebolehbacaan kod ...

PS yang tersangkut pada "memuatkan" apabila boot boleh disebabkan oleh pelbagai sebab: Lumpuhkan plugin yang korup atau bercanggah. Padam atau namakan semula fail konfigurasi yang rosak. Tutup program yang tidak perlu atau menaik taraf memori untuk mengelakkan memori yang tidak mencukupi. Naik taraf ke pemacu keadaan pepejal untuk mempercepatkan bacaan cakera keras. Pasang semula PS untuk membaiki fail sistem rasuah atau isu pakej pemasangan. Lihat maklumat ralat semasa proses permulaan analisis log ralat.

1.0.1 Preface Projek ini (termasuk kod dan komen) telah direkodkan semasa karat saya yang diajar sendiri. Mungkin ada kenyataan yang tidak tepat atau tidak jelas, sila minta maaf. Jika anda mendapat manfaat daripadanya, ia lebih baik. 1.0.2 Mengapa Rustrust boleh dipercayai dan cekap? Karat boleh menggantikan C dan C, dengan prestasi yang sama tetapi keselamatan yang lebih tinggi, dan tidak memerlukan rekompilasi yang kerap untuk memeriksa kesilapan seperti C dan C. Kelebihan utama termasuk: Keselamatan Memori (mencegah penunjuk null dari dereferences, penunjuk menggantung, dan perbalahan data). Thread-safe (pastikan kod multi-threaded selamat sebelum pelaksanaan). Elakkan tingkah laku yang tidak ditentukan (mis., Arus dari batas, pembolehubah yang tidak diinisialisasi, atau akses kepada memori yang dibebaskan). Karat menyediakan ciri bahasa moden seperti generik

Menyelesaikan masalah Permulaan Photoshop Perlahan memerlukan pendekatan berbilang arah, termasuk: menaik taraf perkakasan (memori, pemacu keadaan pepejal, CPU); menyahpasang pemalam yang sudah lapuk atau tidak serasi; membersihkan sampah sistem dan program latar belakang yang berlebihan dengan kerap; menutup program yang tidak relevan dengan berhati -hati; Mengelakkan membuka sejumlah besar fail semasa permulaan.

Alasan pemuatan PS yang perlahan adalah kesan gabungan perkakasan (CPU, memori, cakera keras, kad grafik) dan perisian (sistem, program latar belakang). Penyelesaian termasuk: Menaik taraf perkakasan (terutamanya menggantikan pemacu keadaan pepejal), mengoptimumkan perisian (membersihkan sampah sistem, mengemas kini pemacu, menyemak tetapan PS), dan memproses fail PS. Penyelenggaraan komputer yang kerap juga boleh membantu meningkatkan kelajuan berjalan PS.
