前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python协程

Python协程

作者头像
星哥玩云
发布2022-09-08 13:45:36
2700
发布2022-09-08 13:45:36
举报
文章被收录于专栏:开源部署

一、概念

子程序

在所有的语言中都是层级调用的,比如A中调用B,B在执行过程中调用C,C执行完返回,B执行完返回,最后是A执行完毕。这是通过栈实现的,一个函数就是一个执行的子程序,子程序的调用总是有一个入口、一次返回,调用的顺序是明确的

协程

又称微线程(纤程),是一种用户态的轻量级线程

理解协程

普通理解:线程是系统级别的,它们是由操作系统调度。协程是程序级别,由程序员根据需求自己调度。我们把一个线程中的一个个函数称为子程序,那么一个子程序在执行的过程中可以中断去执行别的子程序,这就是协程。也就是说同一个线程下的一段代码1执行执行着就中断,然后去执行另一段代码2,当再次回来执行代码1时,接着从之前的中断的位置继续向下执行

专业理解:协程拥有自己的寄存器上下文和栈,协程在调度切换时,将寄存器上下文和栈保存到其他的地方,在切换回来时,恢复先前保存的寄存器上下文和栈。因此,协程能后保留一次调用的状态,每次过程重入时,就相当于进入上一次调用的状态

优点

a、无需线程上下文切换的开销,协程避免了无意义的调度,从而提高了性能,但是程序员必须自己承担调度的任务,同时协程也失去了标准线程使用多CPU的能力

b、无需原子操作锁定及同步的开销

c、方便切换控制流,简化编程模型 d、高并发+高可扩展+低成本:一个CPU支持上万个协程不是问题

缺点

a、无法利用多核CPU,协程的本质是单个线程,它不能同时将多个CPU的多个核心使用上,协程需要和进程匹配使用才能运行在多个CPU上。但是一般不需要,除非是CPU计算密集型的应用

代码

代码语言:javascript
复制
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">run1</span><span class="hljs-params">()</span>:</span>
    print(<span class="hljs-number">1</span>)
    print(<span class="hljs-number">2</span>)
    print(<span class="hljs-number">3</span>)
    print(<span class="hljs-number">4</span>)
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">run2</span><span class="hljs-params">()</span>:</span>
    print(<span class="hljs-string">"a"</span>)
    print(<span class="hljs-string">"b"</span>)
    print(<span class="hljs-string">"c"</span>)
    print(<span class="hljs-string">"d"</span>)
run1()
run2()

结果

正常结果

代码语言:javascript
复制
1
2
3
4
a
b
c
d

协程实现的结果(假设)

代码语言:javascript
复制
<span class="hljs-number">1</span>
a
b
<span class="hljs-number">2</span>
<span class="hljs-number">3</span>
c
<span class="hljs-number">4</span>
d

二、数据传递

数据传递

代码语言:javascript
复制
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">func</span><span class="hljs-params">()</span>:</span>
    print(<span class="hljs-string">"------------------1"</span>)
    r = <span class="hljs-keyword">yield</span> <span class="hljs-number">1</span>
    print(<span class="hljs-string">"------------------2"</span>, r)
    <span class="hljs-keyword">yield</span> <span class="hljs-number">2</span>
    print(<span class="hljs-string">"------------------3"</span>)
    <span class="hljs-keyword">yield</span> <span class="hljs-number">3</span>
    print(<span class="hljs-string">"------------------4"</span>)
    <span class="hljs-keyword">yield</span> <span class="hljs-number">4</span>
    print(<span class="hljs-string">"------------------5"</span>)
    <span class="hljs-keyword">yield</span> <span class="hljs-number">5</span>

g = func()
<span class="hljs-comment"># print(next(g))</span>
<span class="hljs-comment"># print(next(g))</span>
<span class="hljs-comment"># print(next(g))</span>
<span class="hljs-comment"># print(next(g))</span>
<span class="hljs-comment"># print(next(g))</span>

<span class="hljs-comment"># 启动生成器g,从第二个开始send的参数值会放到yield处</span>
print(g.send(<span class="hljs-keyword">None</span>))
print(g.send(<span class="hljs-number">11</span>))

生产者与消费者

代码语言:javascript
复制
<span class="hljs-keyword">import</span> time

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">product</span><span class="hljs-params">(c)</span>:</span>
    print(<span class="hljs-string">"启动生产者……"</span>)
    <span class="hljs-comment">#启动消费者</span>
    c.send(<span class="hljs-keyword">None</span>)
    <span class="hljs-keyword">for</span> data <span class="hljs-keyword">in</span> [<span class="hljs-string">"good"</span>, <span class="hljs-string">"nice"</span>, <span class="hljs-string">"cool"</span>, <span class="hljs-string">"handsome"</span>]:
        print(<span class="hljs-string">"生产出%s数据"</span>%(data))
        <span class="hljs-comment">#将数据交给消费者</span>
        c.send(data)
        time.sleep(<span class="hljs-number">2</span>)
    <span class="hljs-comment">#关闭消费者</span>
    c.close()
    print(<span class="hljs-string">"结束生产者……"</span>)

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">customer</span><span class="hljs-params">()</span>:</span>
    print(<span class="hljs-string">"启动消费者……"</span>)
    <span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:
        print(<span class="hljs-string">"等待生产者生产数据"</span>)
        <span class="hljs-comment">#获取数据</span>
        value = <span class="hljs-keyword">yield</span>
        print(<span class="hljs-string">"消费了%s"</span>%value)

c = customer()
product(c)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、概念
  • 二、数据传递
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档