并发编程之协程

1>协程的概念

    基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发。
    对于单线程下,我们不可避免程序中出现io操作,但如果我们能在自己的程序中控制单线程下的多个任务,
    能在一个任务遇到io阻塞时就切换到另外一个任务去计算,这样就保证了该线程能够最大限度地处于就绪态,
    由此便引出了协程的概念,协程的本质就是在单线程下,由用户自己控制一个任务遇到io阻塞了就切换

    另外一个任务去执行,以此来提升效率。

    协程:是单线程下的并发,协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。

    与线程并发的区别:

        >>:python的线程是属于内核级别的,由操作系统控制调度,如耗时过长或I/O阻塞,就会切换到其他线程执行,

        >>:单线程内开启协程,遇到I/O,则由应用程序控制切换,以此来提升效率,

    所以总结协程特点如下:

        只在单个线程实现并发

        修改共享数据不加锁(原理还是切换执行,串行,只是节省了I/O时间,切换之前会保存当前进度,)

        应用程序自己控制

2>greenlet模块

    greenlet模块可以简单地实现多个任务间的直接切换

    如下例子:模拟一个吃饭场景,多数人都喜欢在吃饭的时候玩玩手机,是为‘一边吃饭一边玩手机’,若没有

    并发的时候,如下如图左,只能吃完一口,再吃一口(可以把咀嚼过程理解成I/O,因为这个等待这个动作结束才

    能进入下一个动作),再玩一下手机,再玩一下这种串行方式进行,

    引入协程实现模块greenlet,就可以实现类似于,先送一口饭到嘴里,再一边咀嚼一边玩手机,在等待咀嚼的时候

    (I/O),同步玩手机,也就是并发效果了,如下图右,

    

3>gevent模块

    greenlet有个比较明显的缺陷就是:必须清楚的预知程序的I/O点,并在其之前进行任务切换工作,很明显,不太‘智能’。

    要解决这个问题,就需要引入另一个更强大的库,Gevent,

    Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程。

    g1=gevent.spawn(func,1,2,3,x=4,y=5)创建一个协程对象g1,spawn括号内第一个参数是函数名后面可以
    有多个参数,可以是位置实参或关键字实参,都是传给函数的
    g1.join() # 等待g1结束
    gevent.joinall([g1,g2]) # 等待所有协程执行完毕,参数格式list
    g1.value # 拿到func1的返回值

    

    解析:如上,单线程下运行了eat和play两个任务,最终耗时约等于最大时长的程序,实现了并发效果。

    3.2>优化下

    如上gevent.sleep(1)模拟的是gevent可以识别的io阻塞,
    而time.sleep(1)或其他的阻塞,gevent是不能直接识别的,这时需要引入mokey方法解决,
    from gevent import monkey;monkey.patch_all()必须放到被打补丁者的前面,如time,socket模块之前

    或者要用的话,直接放在文件开头就行了。

    

4>基于协程直线并发的套接字通信

    server端

    

    模拟多线程的用户端


    

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值