简单介绍Python中利用生成器实现的并发编程


Posted in Python onMay 04, 2015

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

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

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

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

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

#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):
  p = produce(l)
  while 1:
    try:
      p.next()
      while len(l) > 0:
        print l.pop()
    except StopIteration:
      sys.exit(0)
l = []
consume(l)

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

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

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 i in l:
    chan.send(i)
chan=stackless.channel()
[stackless.tasklet(output)() for i in xrange(10)]
stackless.tasklet(input)()
stackless.run()

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

Python 相关文章推荐
web.py在SAE中的Session问题解决方法(使用mysql存储)
Jun 24 Python
Python实现随机选择元素功能
Sep 14 Python
python素数筛选法浅析
Mar 19 Python
python中不能连接超时的问题及解决方法
Jun 10 Python
python3第三方爬虫库BeautifulSoup4安装教程
Jun 19 Python
python tornado微信开发入门代码
Aug 24 Python
windows下搭建python scrapy爬虫框架步骤
Dec 23 Python
python实现年会抽奖程序
Jan 22 Python
详解python配置虚拟环境
Apr 08 Python
python 读取更新中的log 或其它文本方式
Dec 24 Python
详解python常用命令行选项与环境变量
Feb 20 Python
使用python实现学生信息管理系统
Feb 25 Python
简单分析Python中用fork()函数生成的子进程
May 04 #Python
python实现从字典中删除元素的方法
May 04 #Python
Python中利用原始套接字进行网络编程的示例
May 04 #Python
python通过索引遍历列表的方法
May 04 #Python
python实现将元祖转换成数组的方法
May 04 #Python
编写Python脚本来获取mp3文件tag信息的教程
May 04 #Python
python通过定义一个类实例作为ftp回调方法
May 04 #Python
You might like
php 删除记录实现代码
2009/03/12 PHP
php数组函数序列之array_splice() - 在数组任意位置插入元素
2011/11/07 PHP
实用的PHP带公钥加密类分享(每次加密结果都不一样哦)
2014/08/20 PHP
php+flash+jQuery多图片上传源码分享
2020/07/27 PHP
php中的抽象方法和抽象类
2017/02/14 PHP
关于JS字符串函数String.replace()
2013/04/07 Javascript
关于编写性能高效的javascript事件的技术
2014/11/28 Javascript
jQuery获得document和window对象宽度和高度的方法
2015/03/25 Javascript
Three.js学习之Lamber材质和Phong材质
2016/08/04 Javascript
炫酷的js手风琴效果
2016/10/13 Javascript
JS 循环li添加点击事件 (闭包的应用)
2016/12/10 Javascript
vue项目中,main.js,App.vue,index.html的调用方法
2018/09/20 Javascript
vue-awesome-swiper 基于vue实现h5滑动翻页效果【推荐】
2018/11/08 Javascript
ES6入门教程之let、const的使用方法
2019/04/13 Javascript
在vue中实现echarts随窗体变化
2020/07/27 Javascript
Vue实现点击导航栏当前标签后变色功能
2020/08/19 Javascript
elementui实现预览图片组件二次封装
2020/12/29 Javascript
Python callable()函数用法实例分析
2018/03/17 Python
pandas把dataframe转成Series,改变列中值的类型方法
2018/04/10 Python
python使用RNN实现文本分类
2018/05/24 Python
简单了解django缓存方式及配置
2019/07/19 Python
Canvas高级路径操作之拖拽对象的实现
2019/08/05 HTML / CSS
德国鞋子网上商店:Omoda.de
2017/03/31 全球购物
J2SDK1.5与J2SDK5.0有什么区别
2012/09/19 面试题
EJB timer的种类
2014/10/28 面试题
函授毕业生的自我鉴定
2013/11/26 职场文书
法制演讲稿
2014/09/10 职场文书
2014年9.18纪念日演讲稿
2014/09/14 职场文书
防灾减灾标语
2014/10/07 职场文书
优秀党员先进事迹材料
2014/12/18 职场文书
党员评议自我评价
2015/03/03 职场文书
《黄山奇石》教学反思
2016/02/18 职场文书
2016年学校禁毒宣传活动工作总结
2016/04/05 职场文书
如何解决springcloud feign 首次调用100%失败的问题
2021/06/23 Java/Android
详解Nginx 被动检查服务器的存活状态
2021/10/16 Servers
2022年四月新番
2022/03/15 日漫