简单介绍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 相关文章推荐
Python算法之栈(stack)的实现
Aug 18 Python
Python实现在matplotlib中两个坐标轴之间画一条直线光标的方法
May 20 Python
解密Python中的描述符(descriptor)
Jun 03 Python
Python使用ftplib实现简易FTP客户端的方法
Jun 03 Python
pycharm远程linux开发和调试代码的方法
Jul 17 Python
基于Python实现定时自动给微信好友发送天气预报
Oct 25 Python
Python实现分段线性插值
Dec 17 Python
windows安装TensorFlow和Keras遇到的问题及其解决方法
Jul 10 Python
python虚拟环境模块venv使用及示例
Mar 04 Python
Python如何存储数据到json文件
Mar 09 Python
Python通过类的组合模拟街道红绿灯
Sep 16 Python
Django mysqlclient安装和使用详解
Sep 17 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
让Nginx支持ThinkPHP的URL重写和PATHINFO的方法分享
2011/08/08 PHP
PHP中explode函数和split函数的区别小结
2016/08/24 PHP
php curl简单采集图片生成base64编码(并附curl函数参数说明)
2019/02/15 PHP
javascript 尚未实现错误解决办法
2008/11/27 Javascript
jquery控制listbox中项的移动并排序的实现代码
2010/09/28 Javascript
Javascript 面试题随笔
2011/03/31 Javascript
JavaScript高级程序设计 读书笔记之十一 内置对象Global
2012/03/07 Javascript
jQuery弹出(alert)select选择的值
2013/04/21 Javascript
根据身份证号自动输出相关信息(籍贯,出身日期,性别)
2013/11/15 Javascript
javascript实现简单的进度条
2015/07/02 Javascript
浅谈JavaScript的内置对象和浏览器对象
2016/06/03 Javascript
JavaScript利用正则表达式替换字符串中的内容
2016/12/12 Javascript
js实现五星评价功能
2017/03/08 Javascript
将angular.js项目整合到.net mvc中的方法详解
2017/06/29 Javascript
js实现简易聊天对话框
2017/08/17 Javascript
基于vue监听滚动事件实现锚点链接平滑滚动的方法
2018/01/17 Javascript
jsonp跨域获取数据的基础教程
2018/07/01 Javascript
JavaScript中 ES6变量的结构赋值
2018/07/10 Javascript
JS实现的视频弹幕效果示例
2018/08/17 Javascript
JavaScript设计模式--简单工厂模式定义与应用案例详解
2020/05/23 Javascript
[48:11]完美世界DOTA2联赛 Magma vs GXR 第二场 11.07
2020/11/10 DOTA
python调用windows api锁定计算机示例
2014/04/17 Python
Python协程的用法和例子详解
2017/09/09 Python
Python实现的爬取百度文库功能示例
2019/02/16 Python
使用IPython或Spyder将省略号表示的内容完整输出
2020/04/20 Python
Python爬虫获取豆瓣电影并写入excel
2020/07/31 Python
使用css3绘制出各种几何图形
2016/08/17 HTML / CSS
Jowissa官方网站:瑞士制造的手表,优雅简约的设计
2020/07/29 全球购物
《穷人》教学反思
2014/04/08 职场文书
高校师德师风自我剖析材料
2014/09/29 职场文书
党员干部三严三实心得体会
2014/10/13 职场文书
2014年工会工作总结
2014/11/12 职场文书
小学教师见习总结
2015/06/23 职场文书
爱心捐款倡议书:点燃希望,传递温暖
2019/11/04 职场文书
Redis 报错 error:NOAUTH Authentication required
2022/05/15 Redis
css样式important规则的正确使用方式
2022/06/10 HTML / CSS