• #协程介绍及基本示例


      

     1 #协程介绍及基本示例
     2 
     3 #Gevent协程(单线程,串行)在线程里启动
     4 '''
     5 协程,又称微线程,纤程。英文名Coroutine。一句话说明什么是线程:
     6         协程是一种用户态的轻量级线程。
     7 
     8 协程拥有自己的寄存器上下文和栈。协程调度切换时,
     9         将寄存器上下文和栈保存到其他地方,在切回来的时候,
    10         恢复先前保存的寄存器上下文和栈。因此:
    11 
    12 协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),
    13         每次过程重入时,就相当于进入上一次调用的状态,换种说法:
    14         进入上一次离开时所处逻辑流的位置。
    15 
    16 协程的好处:
    17 
    18 1无需线程上下文切换的开销
    19 
    20 2无需原子操作锁定及同步的开销
    21   "原子操作(atomic operation)是不需要synchronized",
    22     所谓原子操作是指不会被线程调度机制打断的操作;
    23     这种操作一旦开始,就一直运行到结束,
    24     中间不会有任何 context switch (切换到另一个线程)。
    25     原子操作可以是一个步骤,也可以是多个操作步骤,
    26     但是其顺序是不可以被打乱,或者切割掉只执行部分。
    27     视作整体是原子性的核心。
    28     
    29 3方便切换控制流,简化编程模型
    30 
    31 4高并发+高扩展性+低成本:一个CPU支持上万的协程都不是问题。
    32     所以很适合用于高并发处理。
    33  
    34 
    35 缺点:
    36 
    37 1无法利用多核资源:协程的本质是个单线程,它不能同时将 单个CPU 的多个核用上,
    38         协程需要和进程配合才能运行在多CPU上.
    39         当然我们日常所编写的绝大部分应用都没有这个必要,
    40         除非是cpu密集型应用。
    41         
    42 2进行阻塞(Blocking)操作(如IO时)会阻塞掉整个程序
    43 
    44 
    45 '''
    46 '''
    47 #使用yield实现协程操作例子
    48 
    49 import time
    50 import queue
    51 def consumer(name):
    52     print("--->starting eating baozi...")
    53     while True:
    54         new_baozi = yield  #返回,唤醒接收数据
    55         print("[%s] is eating baozi %s" % (name,new_baozi))
    56         #time.sleep(1)
    57  
    58 def producer():
    59  
    60     r = con.__next__()
    61     r = con2.__next__()
    62     n = 0
    63     while n < 5:
    64         n +=1
    65         con.send(n)#send 的作用唤醒传递数据yield
    66         con2.send(n)
    67         print("1m[producer] is making baozi %s" %n )
    68  
    69  
    70 if __name__ == '__main__':
    71     con = consumer("c1")
    72     con2 = consumer("c2")
    73     p = producer()
    74 
    75 '''
    76 '''
    77 #举例
    78 import time
    79 def home():
    80     print('in func 1')
    81     time.sleep(5)
    82     print('home exec done')
    83 
    84 def bbs():
    85     print('in func 2')
    86     time.sleep(2)
    87 '''
    #协程介绍及基本示例

      

     1 #greenlet #Gevent 的安装
     2 
     3 环境:python 3.6  win 32位
     4 
     5 python下如何安装.whl包?
     6 
     7 下载.whl包
     8 先pip install wheel
     9 
    10 之后pip install 包名字.whl 即可安装某模块包
    11 
    12 
    13 到哪找.whl文件?
    14 http://www.lfd.uci.edu/~gohlke/pythonlibs/
    15 
    16 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    17 https://pypi.python.org/pypi
    18 
    19 https://pypi.python.org/packages/da/78/fbb6d73cf5bc46cc71d2288760afe8ef53beec7850739b61c0d291c1e223/gevent-1.2.2-cp36-cp36m-win32.whl#md5=676cb41e5d265115dae16a969e595882
    20 
    21 https://pypi.python.org/packages/c0/95/49c52a5c354f4115d290cd1210bf71c5aa24481e548ab5a4684a894184fa/greenlet-0.4.12-cp36-cp36m-win32.whl#md5=98b77ae90aa6bc253cf2180a5d807ba9
    22 
    23 
    24 感谢前面的大神铺垫,我总结一下几个注意点:
    25 1.先安装PIP
    26 2.CMD命令进入C:Python34Scripts里面后再执行PIP命令安装pip install wheel
    27 3.把文件最好放在Script文件夹里面再pip install xxxx.whl
    28 4.注意whl文件名不能改 必须一模一样和原名
    29 
    30 
    31 cd C:UsersAdministratorAppDataLocalProgramsPythonPython36-32Scripts
    32 
    33 pip install wheel
    34 
    35 pip install gevent-1.2.2-cp36-cp36m-win32.whl
    #greenlet #Gevent 的安装
    1 pip install wheel
    2 
    3 pip install gevent
    JetBrains PyCharm 5.0.3
     1 #greenlet 已经封装好的协程  #Gevent
     2 #io操作就切换
     3 
     4 '''
     5 greenlet是一个用C实现的协程模块,
     6     相比与python自带的yield,它可以使你在任意函数之间随意切换,
     7     而不需把这个函数先声明为generator
     8 
     9 '''
    10 '''
    11 # -*- coding:utf-8 -*-
    12 from greenlet import greenlet
    13  
    14  
    15 def test1():
    16     print(12)
    17     gr2.switch()
    18     print(34)
    19     gr2.switch()
    20  
    21  
    22 def test2():
    23     print(56)
    24     gr1.switch()
    25     print(78)
    26  
    27  
    28 gr1 = greenlet(test1)#启动一个协程
    29 gr2 = greenlet(test2)
    30 gr1.switch()
    31 '''
    32 
    33 
    34 #Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,
    35 #    在gevent中用到的主要模式是Greenlet,
    36 #    它是以C扩展模块形式接入Python的轻量级协程。
    37 #    Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。
    38 import gevent
    39 #遇到IO就切换,实现并行效果
    40 def foo():
    41     print('running in foo')
    42     gevent.sleep(2)
    43     print('Explicit context switch tofoo again')
    44 
    45 def bar():
    46     print( 'Explicit 精确的   context 内容 to bar')
    47     gevent.sleep(1)
    48     print('Explicit context switch back to bar')
    49 def func3():
    50     print('running func3')
    51     gevent.sleep(0)
    52     print('running func3 again')
    53 
    54 gevent.joinall([
    55     gevent.spawn(foo),
    56     gevent.spawn(bar),
    57     gevent.spawn(func3),
    58 ])
    #greenlet 已经封装好的协程 #Gevent
      1 #协程gevent并发爬网页
      2 '''
      3 from urllib import request
      4 def f(url):
      5     print('GET: %s'% url)
      6     resp = request.urlopen(url)
      7     data = resp.read()
      8     f = open('url.html','wb')
      9     f.write(data)
     10     f.close()
     11     print('%d bytes received from %s'%(len(data),url))
     12 
     13 f('https://www.baidu.com')
     14 
     15 '''
     16 
     17 """
     18 from gevent import monkey; monkey.patch_all()
     19 import gevent
     20 from  urllib.request import urlopen
     21 
     22 def f(url):
     23     print('GET: %s' % url)
     24     resp = urlopen(url)
     25     data = resp.read()
     26     print('%d bytes received from %s.' % (len(data), url))
     27 
     28 gevent.joinall([
     29         gevent.spawn(f, 'https://www.python.org/'),
     30         gevent.spawn(f, 'https://www.yahoo.com/'),
     31         gevent.spawn(f, 'https://github.com/'),
     32 ])
     33 """
     34 
     35 '''
     36 from urllib import request
     37 import gevent
     38 
     39 def f(url):
     40     print('GET: %s'% url)
     41     resp = request.urlopen(url)
     42     data = resp.read()
     43     print('%d bytes received from %s.' % (len(data), url))
     44 
     45 gevent.joinall([
     46     gevent.spawn( f, 'https://www.python.org/'),
     47     gevent.spawn( f, 'https://www.yahoo.com/'),
     48     gevent.spawn( f, 'https://github.com/'),
     49 ])
     50 '''
     51 '''
     52 #同步 串行
     53 from urllib import request
     54 import gevent
     55 import time
     56 def f(url):
     57     print('GET: %s'% url)
     58     resp = request.urlopen(url)
     59     data = resp.read()
     60     print('%d bytes received from %s.' % (len(data), url))
     61 
     62 urls = [
     63     'https://www.python.org/'     ,
     64     'https://www.yahoo.com/'      ,
     65     'https://www.baidu.com/'
     66         ]
     67 
     68 time_start = time.time()
     69 for url in urls:
     70     f(url)
     71 print('同步cost',time.time() - time_start)
     72 '''
     73 
     74 '''
     75 #异步 串行
     76 from urllib import request
     77 import gevent,time
     78 
     79 def f(url):
     80     print('GET: %s'% url)
     81     resp = request.urlopen(url)
     82     data = resp.read()
     83     print('%d bytes received from %s.' % (len(data), url))
     84 
     85 urls = [
     86     'https://www.python.org/'     ,
     87     'https://www.yahoo.com/'      ,
     88     'https://www.baidu.com/'
     89         ]
     90 time_start = time.time()
     91 for url in urls:
     92     f(url)
     93 print('同步cost',time.time() - time_start)
     94 
     95 async_time_start = time.time()
     96 gevent.joinall([
     97     gevent.spawn( f, 'https://www.python.org/'),
     98     gevent.spawn( f, 'https://www.yahoo.com/'),
     99     gevent.spawn( f, 'https://github.com/'),
    100 ])
    101 
    102 print('异步cost',time.time() - async_time_start)
    103 '''
    104 
    105 #异步 串行 补丁 monkey
    106 #多测试几次才能看清楚 (网速会影响结果)
    107 from urllib import request
    108 import gevent,time
    109 from gevent import monkey
    110 
    111 monkey.patch_all()#把当前程序的所有的IO操作给我单独的做上标记
    112 
    113 def f(url):
    114     print('GET: %s'% url)
    115     resp = request.urlopen(url)
    116     data = resp.read()
    117     print('%d bytes received from %s.' % (len(data), url))
    118 
    119 urls = [
    120     'https://www.python.org/'     ,
    121     'https://www.yahoo.com/'      ,
    122     'https://www.baidu.com/'
    123         ]
    124 time_start = time.time()
    125 for url in urls:
    126     f(url)
    127 print('同步cost',time.time() - time_start)
    128 
    129 async_time_start = time.time()
    130 gevent.joinall([
    131     gevent.spawn( f, 'https://www.python.org/'),
    132     gevent.spawn( f, 'https://www.yahoo.com/'),
    133     gevent.spawn( f, 'https://github.com/'),
    134 ])
    135 
    136 print('异步cost',time.time() - async_time_start)
    Vi#协程gevent并发爬网页
  • 相关阅读:
    Javascript-逻辑运算符(&&)
    Javascript-蔬菜运算价格
    Javascript-涨工资案例
    Javascript-数据类型转换
    Javascript-数据类型转换 、 运算符和表达式
    HTML5表单及其验证
    /*使用PHP创建一个数组,保存5個员工的信息(ename/sex/salary/birthday/pic)*/
    CERC2013(C)_Magical GCD
    UVA12546_LCM Pair Sum
    UVA12545_Bits Equalizer
  • 原文地址:https://www.cnblogs.com/ujq3/p/7350186.html
Copyright © 2020-2023  润新知