简单介绍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上传文件和字符到PHP服务器
Nov 24 Python
python脚本作为Windows服务启动代码详解
Feb 11 Python
浅谈Python2、Python3相对路径、绝对路径导入方法
Jun 22 Python
Python 3.x 判断 dict 是否包含某键值的实例讲解
Jul 06 Python
python使用opencv驱动摄像头的方法
Aug 03 Python
python调用百度语音REST API
Aug 30 Python
Python去除字符串前后空格的几种方法
Mar 04 Python
树莓派4B+opencv4+python 打开摄像头的实现方法
Oct 18 Python
Python中如何添加自定义模块
Jun 09 Python
python 命令行传参方法总结
May 25 Python
忆童年!用Python实现愤怒的小鸟游戏
Jun 07 Python
使用python求解迷宫问题的三种实现方法
Mar 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
PHP中Notice错误常见解决方法
2017/04/28 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
2017/11/14 PHP
php使用goto实现自动重启swoole、reactphp、workerman服务的代码
2020/04/13 PHP
在第一个input框内输入内容.textarea自动得到第一个文件框的值的javascript代码
2007/04/20 Javascript
用JS实现一个TreeMenu效果分享
2011/08/28 Javascript
js判读浏览器是否支持html5的canvas的代码
2013/11/18 Javascript
Google Dart编程语法和基本类型学习教程
2013/11/27 Javascript
浅谈JS继承_借用构造函数 &amp; 组合式继承
2016/08/16 Javascript
axios学习教程全攻略
2017/03/26 Javascript
bootstrap栅格系统示例代码分享
2017/05/22 Javascript
详解angularJs中关于ng-class的三种使用方式说明
2017/06/02 Javascript
基于vue v-for 多层循环嵌套获取行数的方法
2018/09/26 Javascript
js实现同一个页面,多个enter事件绑定的示例
2018/10/10 Javascript
JavaScript基于数组实现的栈与队列操作示例
2018/12/22 Javascript
浅谈小程序 setData学问多
2019/02/20 Javascript
[03:55]2014DOTA2国际邀请赛 Fnatic经理采访赢DK在情理之中
2014/07/10 DOTA
[47:42]Fnatic vs Liquid 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python中的闭包总结
2014/09/18 Python
python自定义异常实例详解
2017/07/11 Python
Python中read()、readline()和readlines()三者间的区别和用法
2017/07/30 Python
Python实现备份MySQL数据库的方法示例
2018/01/11 Python
Python cookbook(数据结构与算法)同时对数据做转换和换算处理操作示例
2018/03/23 Python
Python下调用Linux的Shell命令的方法
2018/06/12 Python
在PyCharm下打包*.py程序成.exe的方法
2018/11/29 Python
Django框架模板的使用方法示例
2019/05/25 Python
Django实现后台上传并显示图片功能
2020/05/29 Python
荷兰照明、灯具和配件网上商店:dmlights
2019/08/25 全球购物
英国最大的在线照明商店:Litecraft
2020/08/31 全球购物
销售主管岗位职责
2014/02/08 职场文书
硕士研究生求职自荐信范文
2014/03/11 职场文书
学雷锋先进个人事迹
2014/05/26 职场文书
预备党员综合考察材料
2014/05/31 职场文书
低碳日宣传活动总结
2014/07/09 职场文书
对党的十八届四中全会的期盼
2014/10/17 职场文书
党员干部学习心得体会
2016/01/23 职场文书
学长教您写论文:经验总结
2019/07/09 职场文书