Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5102473
  • 博文数量: 921
  • 博客积分: 16037
  • 博客等级: 上将
  • 技术积分: 8469
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-05 02:08
文章分类

全部博文(921)

文章存档

2020年(1)

2019年(3)

2018年(3)

2017年(6)

2016年(47)

2015年(72)

2014年(25)

2013年(72)

2012年(125)

2011年(182)

2010年(42)

2009年(14)

2008年(85)

2007年(89)

2006年(155)

分类: Python/Ruby

2015-10-10 16:06:21

我们都知道并发(不是并行)编程目前有四种方式,多进程,多线程,异步,和协程。
多进程编程在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. #coding=utf-8
  2. import time
  3. import sys
  4. # 生产者
  5. def produce(l):
  6.     i=0
  7.     while 1:
  8.         if i < 5:
  9.             l.append(i)
  10.             yield i
  11.             i=i+1
  12.             time.sleep(1)
  13.         else:
  14.             return
  15.       
  16. # 消费者
  17. def consume(l):
  18.     p = produce(l)
  19.     while 1:
  20.         try:
  21.             p.next()
  22.             while len(l) > 0:
  23.                 print l.pop()
  24.         except StopIteration:
  25.             sys.exit(0)
  26. l = []
  27. consume(l)
在上面的例子中,当程序执行到produce的yield i时,返回了一个generator,当我们在custom中调用p.next(),程序又返回到produce的yield i继续执行,这样l中又append了元素,然后我们print l.pop(),直到p.next()引发了StopIteration异常。
通过上面的例子我们看到协程的调度对于内核来说是不可见的,协程间是协同调度的,这使得并发量在上万的时候,协程的性能是远高于线程的。


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

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

原文地址


阅读(3123) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~