简单介绍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 抓取动态网页内容方案详解
Dec 25 Python
Python学习笔记整理3之输入输出、python eval函数
Dec 14 Python
python微信公众号开发简单流程
Mar 23 Python
Python if语句知识点用法总结
Jun 10 Python
python3实现域名查询和whois查询功能
Jun 21 Python
在Pycharm中将pyinstaller加入External Tools的方法
Jan 16 Python
对PyQt5中的菜单栏和工具栏实例详解
Jun 20 Python
PyQt5根据控件Id获取控件对象的方法
Jun 25 Python
python判断一个对象是否可迭代的例子
Jul 22 Python
Python3 mmap内存映射文件示例解析
Mar 23 Python
Python提取视频中图片的示例(按帧、按秒)
Oct 22 Python
Python3 + Appium + 安卓模拟器实现APP自动化测试并生成测试报告
Jan 27 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 mkdir()定义和用法
2009/01/14 PHP
IIS6.0 开启Gzip方法及PHP Gzip函数分享
2014/06/08 PHP
PHP5.3以上版本安装ZendOptimizer扩展
2015/03/27 PHP
PHP的PDO常用类库实例分析
2016/04/07 PHP
yii2分页之实现跳转到具体某页的实例代码
2016/06/02 PHP
php 调用ffmpeg获取视频信息的简单实现
2017/04/03 PHP
PHP实现深度优先搜索算法(DFS,Depth First Search)详解
2017/09/16 PHP
php学习笔记之字符串常见操作总结
2019/07/16 PHP
JS启动应用程序的一个简单例子
2008/05/11 Javascript
js中将字符串转换成json的三种方式
2011/01/12 Javascript
node.js开机自启动脚本文件
2014/12/24 Javascript
javascript轻量级库createjs使用Easel实现拖拽效果
2016/02/19 Javascript
jquery Banner轮播选项卡
2016/12/26 Javascript
JS中setTimeout和setInterval的最大延时值详解
2017/02/13 Javascript
xmlplus组件设计系列之按钮(2)
2017/04/26 Javascript
React Native基础入门之初步使用Flexbox布局
2018/07/02 Javascript
[03:02]2014DOTA2西雅图邀请赛 让队员自己告诉你DK NAVI备战情况
2014/07/08 DOTA
[05:08]第一届“网鱼杯”DOTA2比赛精彩集锦
2014/09/05 DOTA
Python中使用HTMLParser解析html实例
2015/02/08 Python
python smtplib模块实现发送邮件带附件sendmail
2018/05/22 Python
用Python编写一个简单的CS架构后门的方法
2018/11/20 Python
Python 使用folium绘制leaflet地图的实现方法
2019/07/05 Python
pytorch 实现将自己的图片数据处理成可以训练的图片类型
2020/01/08 Python
python PIL/cv2/base64相互转换实例
2020/01/09 Python
Python的in,is和id函数代码实例
2020/04/18 Python
对Matlab中共轭、转置和共轭装置的区别说明
2020/05/11 Python
如何使用Python处理HDF格式数据及可视化问题
2020/06/24 Python
CSS3 clip-path 用法介绍详解
2018/03/01 HTML / CSS
英国最大的女性服装零售商:Dorothy Perkins
2017/03/30 全球购物
英国太阳镜品牌:Taylor Morris Eyewear
2018/04/18 全球购物
伦敦新晋轻奢耳饰潮牌:Tada & Toy
2020/05/25 全球购物
如何写一封打动人心的求职信
2014/02/17 职场文书
小学生个人先进事迹材料
2014/05/08 职场文书
行政专员岗位职责说明书
2014/07/30 职场文书
个人维稳承诺书
2015/05/04 职场文书
MySQL学习之基础操作总结
2022/03/19 MySQL