简单介绍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实现抓取城市的PM2.5浓度和排名
Mar 19 Python
在Django框架中编写Context处理器的方法
Jul 20 Python
python高手之路python处理excel文件(方法汇总)
Jan 07 Python
matplotlib 纵坐标轴显示数据值的实例
May 25 Python
python单例模式获取IP代理的方法详解
Sep 13 Python
Django的用户模块与权限系统的示例代码
Jul 24 Python
python使用Matplotlib改变坐标轴的默认位置
Oct 18 Python
python实现多进程按序号批量修改文件名的方法示例
Dec 30 Python
Python类如何定义私有变量
Feb 03 Python
关于Tensorflow使用CPU报错的解决方式
Feb 05 Python
django 连接数据库出现1045错误的解决方式
May 14 Python
python中count函数知识点浅析
Dec 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
使用PHPMYADMIN操作mysql数据库添加新用户和数据库的方法
2010/04/02 PHP
Laravel5.5以下版本中如何自定义日志行为详解
2018/08/01 PHP
Nigma vs Liquid BO3 第一场2.14
2021/03/10 DOTA
jQuery学习笔记之jQuery的动画
2010/12/22 Javascript
兼容IE、FireFox、Chrome等浏览器的xml处理函数js代码
2011/11/30 Javascript
Egret引擎开发指南之编译项目
2014/09/03 Javascript
EasyUI实现第二层弹出框的方法
2015/03/01 Javascript
jQuery leonaScroll 1.1 自定义滚动条插件(推荐)
2016/09/17 Javascript
jquery实时获取时间的简单实例
2017/01/26 Javascript
详解Sea.js中Module.exports和exports的区别
2017/02/12 Javascript
ES6中的箭头函数实例详解
2017/04/06 Javascript
JS+HTML5 FileReader对象用法示例
2017/04/07 Javascript
基于zepto.js实现登录界面
2017/10/09 Javascript
Vue2.0子同级组件之间数据交互方法
2018/02/28 Javascript
Nodejs使用Mongodb存储与提供后端CRD服务详解
2018/09/04 NodeJs
webpack的pitching loader详解
2019/09/23 Javascript
python完成FizzBuzzWhizz问题(拉勾网面试题)示例
2014/05/05 Python
Python 2.7.x 和 3.x 版本的重要区别小结
2014/11/28 Python
python实现的DES加密算法和3DES加密算法实例
2015/06/03 Python
python3 模拟登录v2ex实例讲解
2017/07/13 Python
Python编程求质数实例代码
2018/01/31 Python
对python当中不在本路径的py文件的引用详解
2018/12/15 Python
python实现多层感知器
2019/01/18 Python
Python如何用wx模块创建文本编辑器
2020/06/07 Python
selenium+超级鹰实现模拟登录12306
2021/01/24 Python
css背景图片的背景裁切、背景透明度、背景变换等效果运用
2012/12/24 HTML / CSS
浅谈Html5多线程开发之WebWorkers
2018/05/02 HTML / CSS
美国嘻哈文化生活方式品牌:GLD
2018/04/15 全球购物
OSPF有什么优点?为什么OSPF比RIP收敛快?
2013/02/13 面试题
linux面试题参考答案(2)
2015/12/06 面试题
副护士长竞聘演讲稿
2014/04/30 职场文书
2014年教师批评与自我批评思想汇报
2014/09/20 职场文书
2014年创卫工作总结
2014/11/24 职场文书
个性发展自我评价2015
2015/03/09 职场文书
关于应聘教师的自荐信
2016/01/28 职场文书
《酸的和甜的》教学反思
2016/02/18 职场文书