zoukankan      html  css  js  c++  java
  • python第16天-网络4

    协程

    又叫微线程,coroutine,可以认为是比线程更小的执行单元,自带CPU上下文,。

    通俗理解:在一个线程的某个函数,可以再任何地方保存当前函数的一些临时变量等信息,然后切换到另一个函数执行,并且切换的次数和什么时候再切换到原来的函数由开发者自己确定。

    协程和线程差异

    线程非常耗性能,从系统层面远不止保存和恢复CPU上下文,OS的每个线程都有自己缓存Cache等数据等。协程的切换只是单纯操作CPU上下文

    # coding=utf-8
    import time
    import sys
    sys.setrecursionlimit(10000)
    
    def A():
        while True:
            print("---A---")
            yield
            time.sleep(0.5)
    
    def B(c):
        while True:
            print("---B---")
            c.__next__()
            time.sleep(0.5)
    
    if __name__=="__main__":
        a=A()
        B(a)

    运行结果

    ---B---
    ---A---
    ---B---
    ---A---
    ---B---
    ---A---
    ---B---
    ---A---

    但是用生成器来做协程感觉不是很优美,greenlet

    sudo pip install greenlet#python3导入pip3
    
    #coding=utf-8
    
    from greenlet import greenlet
    import time
    
    def test1():
    	while True:
    		print("---A---")
    		gr2.switch()
    		time.sleep(0.5)
    
    def test2():
    	while True:
    		print("---B---")
    		gr1.switch()
    		time.sleep(0.5)
    
    gr1 = greenlet(test1)
    gr2 = greenlet(test2)
    
    #切换到gr1中运行
    gr1.switch()

    greenlet的底层代码由C语言写的,运行结果一样

    gevent比greenlet更强大,自动切换任务,原理是当一个greenlet遇到耗时操作如访问网络时,会自动切换到其他greenlet,操作完成再切换回来继续执行。

    #coding=utf-8
    import gevent
    
    def f(n):
    	for i in range(n):
    		print gevent.getcurrent(), i
    
    g1 = gevent.spawn(f, 5)
    g2 = gevent.spawn(f, 5)
    g3 = gevent.spawn(f, 5)
    g1.join()
    g2.join()
    g3.join()

    运行结果:3个greenlet依次运行而不是交替运行

    <Greenlet at 0x10e49f550: f(5)> 0
    <Greenlet at 0x10e49f550: f(5)> 1
    <Greenlet at 0x10e49f550: f(5)> 2
    <Greenlet at 0x10e49f550: f(5)> 3
    <Greenlet at 0x10e49f550: f(5)> 4
    <Greenlet at 0x10e49f910: f(5)> 0
    <Greenlet at 0x10e49f910: f(5)> 1
    <Greenlet at 0x10e49f910: f(5)> 2
    <Greenlet at 0x10e49f910: f(5)> 3
    <Greenlet at 0x10e49f910: f(5)> 4
    <Greenlet at 0x10e49f4b0: f(5)> 0
    <Greenlet at 0x10e49f4b0: f(5)> 1
    <Greenlet at 0x10e49f4b0: f(5)> 2
    <Greenlet at 0x10e49f4b0: f(5)> 3
    <Greenlet at 0x10e49f4b0: f(5)> 4

    gevent切换执行

    #coding=utf-8
    import gevent
    
    def f(n):
    	for i in range(n):
    		print gevent.getcurrent(), i
    		#⽤来模拟⼀个耗时操作, 注意不是time模块中的sleep
    		gevent.sleep(1)
    g1 = gevent.spawn(f, 5)
    g2 = gevent.spawn(f, 5)
    g3 = gevent.spawn(f, 5)
    g1.join()
    g2.join()
    g3.join()

    运行结果 3个greenlet交替运行

    <Greenlet at 0x7fa70ffa1c30: f(5)> 0
    <Greenlet at 0x7fa70ffa1870: f(5)> 0
    <Greenlet at 0x7fa70ffa1eb0: f(5)> 0
    <Greenlet at 0x7fa70ffa1c30: f(5)> 1
    <Greenlet at 0x7fa70ffa1870: f(5)> 1
    <Greenlet at 0x7fa70ffa1eb0: f(5)> 1
    <Greenlet at 0x7fa70ffa1c30: f(5)> 2
    <Greenlet at 0x7fa70ffa1870: f(5)> 2
    <Greenlet at 0x7fa70ffa1eb0: f(5)> 2
    <Greenlet at 0x7fa70ffa1c30: f(5)> 3
    <Greenlet at 0x7fa70ffa1870: f(5)> 3
    <Greenlet at 0x7fa70ffa1eb0: f(5)> 3
    <Greenlet at 0x7fa70ffa1c30: f(5)> 4
    <Greenlet at 0x7fa70ffa1870: f(5)> 4
    <Greenlet at 0x7fa70ffa1eb0: f(5)> 4

    gevent版服务器 monkey打补丁,动态修改下边的代码

  • 相关阅读:
    ajax 传递参数中文乱码解决办法
    jQuery 时间戳转化成时间
    IDEA2017 导入 SVN上的 Myeclipse或Eclipse 项目
    ajax返回json数据,对其中日期的解析
    MYSQL 按照字母排序查询
    JVM介绍
    正则表达式
    could not find the main class错误
    转:MyEclipse使用总结——MyEclipse10安装SVN插件
    转:Oracle数据库sqlplus与plsqldev解决乱码
  • 原文地址:https://www.cnblogs.com/wangjinliang1991/p/9898905.html
Copyright © 2011-2022 走看看