简单介绍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 相关文章推荐
Pyramid将models.py文件的内容分布到多个文件的方法
Nov 27 Python
python超简单解决约瑟夫环问题
May 12 Python
Python循环语句之break与continue的用法
Oct 14 Python
Python与Java间Socket通信实例代码
Mar 06 Python
python 第三方库的安装及pip的使用详解
May 11 Python
Python在groupby分组后提取指定位置记录方法
Apr 20 Python
Django之模板层的实现代码
Sep 09 Python
Python容器使用的5个技巧和2个误区总结
Sep 26 Python
python全局变量引用与修改过程解析
Jan 07 Python
virtualenv介绍及简明教程
Jun 23 Python
python全栈开发语法总结
Nov 22 Python
Python基础 括号()[]{}的详解
Nov 07 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中如何在有限的内存中读取大文件
2013/07/02 PHP
zf框架的session会话周期及次数限制使用示例
2014/03/13 PHP
PHP跨平台获取服务器IP地址自定义函数分享
2014/12/29 PHP
10个超级有用值得收藏的PHP代码片段
2015/01/22 PHP
PHP实现一维数组转二维数组的方法
2015/02/25 PHP
Thinkphp实现站点静态化的方法详解
2017/03/21 PHP
JS获取dom 对象 ajax操作 读写cookie函数
2009/11/18 Javascript
jQuery 拖动层(在可视区域范围内)
2012/05/24 Javascript
js实现飞入星星特效代码
2014/10/17 Javascript
浅谈Javascript如何实现匀速运动
2014/12/19 Javascript
浅谈JSON.parse()和JSON.stringify()
2015/07/14 Javascript
JavaScript实现垂直向上无缝滚动特效代码
2016/11/23 Javascript
js实现固定宽高滑动轮播图效果
2017/01/13 Javascript
JS三目运算(三元运算)方法详解
2017/03/01 Javascript
浅谈通过JS拦截 pushState和replaceState事件
2017/07/21 Javascript
javascript实现电脑和手机版样式切换
2017/11/10 Javascript
Vue.JS实现垂直方向展开、收缩不定高度模块的JS组件
2018/06/19 Javascript
Vant的安装和配合引入Vue.js项目里的方法步骤
2018/12/05 Javascript
vue封装可复用组件confirm,并绑定在vue原型上的示例
2019/10/31 Javascript
Python爬取数据并写入MySQL数据库的实例
2018/06/21 Python
使用Flask集成bootstrap的方法
2018/07/24 Python
使用python对文件中的数值进行累加的实例
2018/11/28 Python
Python实现FTP弱口令扫描器的方法示例
2019/01/31 Python
python3.7 的新特性详解
2019/07/25 Python
python模拟预测一下新型冠状病毒肺炎的数据
2020/02/01 Python
python怎么调用自己的函数
2020/07/01 Python
vue路由实现登录拦截
2021/03/24 Vue.js
水务局局长岗位职责
2013/11/28 职场文书
打架检讨书800字
2014/01/10 职场文书
24岁生日感言
2014/01/13 职场文书
《大禹治水》教学反思
2014/04/27 职场文书
建筑工地门卫岗位职责
2014/04/30 职场文书
预备党员入党感言
2015/08/01 职场文书
高中政治教学反思
2016/02/23 职场文书
详解python的异常捕获
2022/03/03 Python
浅谈Redis 中的过期删除策略和内存淘汰机制
2022/04/03 Redis