• 高性能python编程之协程(stackless)-乾颐堂


    我们都知道并发(不是并行)编程目前有四种方式,多进程,多线程,异步,和协程。

    多进程编程在python中有类似C的os.fork,当然还有更高层封装的multiprocessing标准库,在之前写过的python高可用程序设计方法http://www.cnblogs.com/hymenz/p/3488837.html中提供了类似nginx中master process和worker process间信号处理的方式,保证了业务进程的退出可以被主进程感知。

    多线程编程python中有Thread和threading,在linux下所谓的线程,实际上是LWP轻量级进程,其在内核中具有和进程相同的调度方式,有关LWP,COW(写时拷贝),fork,vfork,clone等的资料较多,这里不再赘述。

    异步在linux下主要有三种实现select,poll,epoll,关于异步不是本文的重点。

    说协程肯定要说yield,我们先来看一个例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #coding=utf-8
    import time
    import sys
    # 生产者
    def produce(l):
        i=0
        while 1:
            if i < 5:
                l.append(i)
                yield i
                i=i+1
                time.sleep(1)
            else:
                return
           
    # 消费者
    def consume(l):
        = produce(l)
        while 1:
            try:
                p.next()
                while len(l) > 0:
                    print l.pop()
            except StopIteration:
                sys.exit(0)
    = []
    consume(l)

    在上面的例子中,当程序执行到produce的yield i时,返回了一个generator,当我们在custom中调用p.next(),程序又返回到produce的yield i继续执行,这样l中又append了元素,然后我们print l.pop(),直到p.next()引发了StopIteration异常。

    通过上面的例子我们看到协程的调度对于内核来说是不可见的,协程间是协同调度的,这使得并发量在上万的时候,协程的性能是远高于线程的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import stackless
    import urllib2
    def output():
        while 1:
            url=chan.receive()
            print url
            f=urllib2.urlopen(url)
            #print f.read()
            print stackless.getcurrent()
          
    def input():
        f=open('url.txt')
        l=f.readlines()
        for in l:
            chan.send(i)
    chan=stackless.channel()
    [stackless.tasklet(output)() for in xrange(10)]
    stackless.tasklet(input)()
    stackless.run()

    关于协程,可以参考greenlet,stackless,gevent,eventlet等的实现。

    www.qytang.com/
    http://www.qytang.com/cn/list/29/
    http://www.qytang.com/cn/list/28/446.htm
    http://www.qytang.com/cn/list/28/445.htm
    http://www.qytang.com/cn/list/28/444.htm
    http://www.qytang.com/cn/list/28/442.htm
    http://www.qytang.com/cn/list/28/440.htm
    http://www.qytang.com/cn/list/28/437.htm
    http://www.qytang.com/cn/list/28/435.htm
    http://www.qytang.com/cn/list/28/434.htm
    http://www.qytang.com/cn/list/28/433.htm
    http://www.qytang.com/cn/list/28/431.htm
    http://www.qytang.com/cn/list/28/328.htm
    http://www.qytang.com/cn/list/28/326.htm
    http://www.qytang.com/cn/list/28/429.htm

  • 相关阅读:
    通过进程ID获取基地址
    怎样获得某个进程的内存基地址?
    Delphi来实现一个IP地址输入控件
    如何在Windows服务程序中添加U盘插拔的消息
    delphi Format格式化函数
    CRC8算法DELPHI源码
    实现控件的透明背景
    定制控件背景颜色与背景位图
    实现系统滚动条换肤功能
    Delphi 获取命令行输出的函数
  • 原文地址:https://www.cnblogs.com/qytang/p/5580871.html
Copyright © 2020-2023  润新知