简单介绍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程序中使用Cookie的教程
Apr 30 Python
Python函数返回值实例分析
Jun 08 Python
python基础教程之分支、循环简单用法
Jun 16 Python
python logging 日志轮转文件不删除问题的解决方法
Aug 02 Python
详解Golang 与python中的字符串反转
Jul 21 Python
Python使用Selenium+BeautifulSoup爬取淘宝搜索页
Feb 24 Python
Python这样操作能存储100多万行的xlsx文件
Apr 16 Python
python实现网站用户名密码自动登录功能
Aug 09 Python
Series和DataFrame使用简单入门
Nov 13 Python
3种适用于Python的疯狂秘密武器及原因解析
Apr 29 Python
python中怎么表示空值
Jun 19 Python
python 实现控制鼠标键盘
Nov 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数组排序usort、uksort与sort函数用法
2014/11/17 PHP
Symfony数据校验方法实例分析
2015/01/26 PHP
php中使用in_array() foreach array_search() 查找数组是否包含时的性能对比
2015/04/14 PHP
PHP中类属性与类静态变量的访问方法示例
2016/07/13 PHP
PHP Socket网络操作类定义与用法示例
2017/08/30 PHP
验证用户是否修改过页面的数据的实现方法
2008/09/26 Javascript
JS正则中的RegExp对象对象
2012/11/07 Javascript
Jquery submit()无法提交问题
2013/04/21 Javascript
PHP中使用微秒计算脚本执行时间例子
2014/11/19 Javascript
javascript实现根据iphone屏幕方向调用不同样式表的方法
2015/07/13 Javascript
整理Javascript基础入门学习笔记
2015/11/29 Javascript
Angular 页面跳转时传参问题
2016/08/01 Javascript
探索Javascript中this的奥秘
2016/12/11 Javascript
JS获取填报扩展单元格控件的值的解决办法
2017/07/14 Javascript
详解Require.js与Sea.js的区别
2018/08/05 Javascript
微信小程序提交form操作示例
2018/12/30 Javascript
nodejs微信开发之自动回复的实现
2019/03/17 NodeJs
[01:14]2019完美世界城市挑战赛(秋季赛)全国总决赛精彩花絮
2020/01/08 DOTA
详解python执行shell脚本创建用户及相关操作
2019/04/11 Python
详解python和matlab的优势与区别
2019/06/28 Python
对Python中小整数对象池和大整数对象池的使用详解
2019/07/09 Python
Django框架视图层URL映射与反向解析实例分析
2019/07/29 Python
Python读取csv文件实例解析
2019/12/30 Python
使用 Python 处理3万多条数据只要几秒钟
2020/01/19 Python
Python Selenium库的基本使用教程
2021/01/04 Python
基于CSS3的CSS 多栏(Multi-column)实现瀑布流源码分享
2014/06/11 HTML / CSS
HTML5打开手机扫码功能及优缺点
2017/11/27 HTML / CSS
大韩航空官方网站:Korean Air
2017/10/25 全球购物
英国工艺品购物网站:Minerva Crafts
2018/01/29 全球购物
印尼网上商店:Alfacart.com
2019/03/11 全球购物
教育科学研究生自荐信
2013/10/09 职场文书
大学新生欢迎词
2014/01/10 职场文书
查摆问题对照检查材料
2014/08/28 职场文书
2015年物业管理工作总结
2015/04/23 职场文书
Nginx反向代理及负载均衡如何实现(基于linux)
2021/03/31 Servers
Python+DeOldify实现老照片上色功能
2022/06/21 Python