zoukankan      html  css  js  c++  java
  • (12)协程

    什么是协程:就是低消耗的线程

    我们想要开启多任务,但是消耗要比线程更低,这样就诞生了协程(单线程下实现并发的效果,这种效果就是协程)

    协程的目的:就是单线程实现并发

    协程的优点:相对于操作系统内置的控制cpu切换的程序消耗少一点

    协程的缺点:如果程序里面需要使用到协程,必须监控程序里面所有的IO情况,如果不做处理,后面所有的任务都不会执行(因为是单线程,单任务,所以cup无法切换)

    什么时候使用协程:又以下实例可以得知,在单线程下,遇到IO的时候比较合适,如果没有IO则串行的执行效率要比协程高

    协程使用场景实例
    import time

    '''基于yield的协程'''
    def func1():
    while True:
    print('func1')
    yield


    def func2():
    g = func1()
    for i in range(10000000):
    print('func2')
    next(g)


    start = time.time()
    func2()
    print('协程的执行时间:',time.time() - start)


    '''串行的执行时间,用来和协程的执行耗费对比'''
    def func3():
    for i in range(10000000):
    pass

    def func4():
    for i in range(10000000):
    pass

    start = time.time()
    func3()
    func4()
    print('串行的执行时间:',time.time() - start)

    开启协程:通过gevent包来实现协程(这个包实第三方包)

    import time

    import gevent # 通过这个gevent模块来实现单线程下的协程

    '''模拟现实中的协程'''


    def eat(name):
    print('%s is eat 1' % name)
       '''gecent只监控自己所在的任务下的IO情况'''
    gevent.sleep(1) # 如果使用gevent模块,则sleep功能就不能用time模块下的,必须使用gevent模块下的sleep
    print('%s is eat 2' % name)


    def play(name):
    print('%s is play 1' % name)
    gevent.sleep(2)
    print('%s is play 2' % name)


    '''实例化gevent模块,提交函数spawn里面可以传入参数,一个是需要执行的任务名称,一个是传入的name名称'''
    start = time.time()
    g1 = gevent.spawn(eat, 'zekai') # gevent模块下的spawn就是用来提交上面函数任务的,异步的执行
    g2 = gevent.spawn(play, 'steven')
    g1.join() # 使用join来等待协程执行完
    g2.join()

    print('执行时间:', time.time() - start)

    PS:主线程开启后就先执行了g1,然后由于协程是异步的,所以也同时开启了g2,主线程也在往下运行,这时候g1在执行任务的时候遇到了IO,g1遇到IO的时候g2也在执行,这时候g2也遇到了IO,然后再g2执行IO的时候g1的IO执行完了(g1所有的程序都成功执行),由于我们不知道协程什么时候执行完,为了让程序能够完整的执行,需要用到join函数来等待协程执行完毕,主线程再往下执行

    开启协程:通过gevent包来实现协程(监控程序下所有的IO情况)

    import time

    import gevent # 通过这个gevent模块来实现单线程下的协程
    from gevent import monkey #要实现监控程序下所有的IO情况需要从gevent包内倒入monkey模块

    monkey.patch_all() #开启监控程序里所有IO的情况
    def eat(name):
    print('%s is eat 1' % name)
    time.sleep(1) # 如果使用gevent模块,则sleep功能就不能用time模块下的,必须使用gevent模块下的sleep
    print('%s is eat 2' % name)


    def play(name):
    print('%s is play 1' % name)
    time.sleep(2)
    print('%s is play 2' % name)


    '''实例化gevent模块,提交函数spawn里面可以传入参数,一个是需要执行的任务名称,一个是传入的name名称'''
    start = time.time()
    g1 = gevent.spawn(eat, 'zekai') # gevent模块下的spawn就是用来提交上面函数任务的,异步的执行
    g2 = gevent.spawn(play, 'steven')
    g1.join() # join会等待所有协程(子线程、子进程)执行完毕再执行主线程(主进程)
    g2.join()

    print('执行时间:', time.time() - start)

     

  • 相关阅读:
    什么造就一个伟大的站点
    我的一些关于商业计划书的经验
    iPhone开发:万能的NSData
    两种快速打乱NSMutableArray的方法
    交大校友:互联网大佬们
    程序员的十层楼 11层(上帝)
    iPhone开发:使用NSValue存储任意类型的数据
    Linux之lsof命令
    MySQL密码忘了怎么办?MySQL重置root密码方法
    nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address
  • 原文地址:https://www.cnblogs.com/shizhengquan/p/10297822.html
Copyright © 2011-2022 走看看