简单介绍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中的多重继承实例讲解
Sep 28 Python
python 爬取微信文章
Jan 30 Python
Python随机生成数据后插入到PostgreSQL
Jul 28 Python
简单实现Python爬取网络图片
Apr 01 Python
Python netmiko模块的使用
Feb 14 Python
Python图像处理库PIL的ImageFilter模块使用介绍
Feb 26 Python
pymysql 插入数据 转义处理方式
Mar 02 Python
python 写函数在一定条件下需要调用自身时的写法说明
Jun 01 Python
python新手学习使用库
Jun 11 Python
pycharm激活码免费分享适用最新pycharm2020.2.3永久激活
Nov 25 Python
python3实现简单飞机大战
Nov 29 Python
七个非常实用的Python工具包总结
Jun 15 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
《DOTA3》开发工作已经开始 《DOTA3》将代替《DOTA2》
2021/03/06 DOTA
json的键名为数字时的调用方式(示例代码)
2013/11/15 PHP
php+mysql+jquery实现日历签到功能
2017/02/27 PHP
PHP封装的mysqli数据库操作类示例
2019/02/16 PHP
JavaScript事件列表解说
2006/12/22 Javascript
写自已的js类库需要的核心代码
2012/07/16 Javascript
javascript生成随机数的方法
2014/05/16 Javascript
nodejs npm包管理的配置方法及常用命令介绍
2014/06/05 NodeJs
教你如何使用node.js制作代理服务器
2014/11/26 Javascript
纯JavaScript实现的兼容各浏览器的添加和移除事件封装
2015/03/28 Javascript
jquery轮播的实现方式 附完整实例
2016/07/28 Javascript
jquery对Json的各种遍历方法总结(必看篇)
2016/09/29 Javascript
HTML Table 空白单元格补全的简单实现
2016/10/13 Javascript
Javascript中 带名 匿名 箭头函数的重要区别(推荐)
2017/01/29 Javascript
利用NPM淘宝的node.js镜像加速nvm
2017/03/27 Javascript
微信小程序教程系列之新建页面(4)
2017/04/17 Javascript
JavaScript定时器setTimeout()和setInterval()详解
2017/08/18 Javascript
JavaScript中递归实现的方法及其区别
2017/09/12 Javascript
React 项目迁移 Webpack Babel7的实现
2018/09/12 Javascript
微信小程序实现比较功能的方法汇总(五种方法)
2020/03/07 Javascript
Python字典操作简明总结
2015/04/13 Python
Python Socket实现简单TCP Server/client功能示例
2017/08/05 Python
python 利用文件锁单例执行脚本的方法
2019/02/19 Python
python中append实例用法总结
2019/07/30 Python
Python元组 tuple的概念与基本操作详解【定义、创建、访问、计数、推导式等】
2019/10/30 Python
Python实现一个优先级队列的方法
2020/07/31 Python
python的launcher用法知识点总结
2020/08/07 Python
html5适合移动应用开发的12大特性
2014/03/19 HTML / CSS
Shell如何接收变量输入
2012/09/24 面试题
厂长助理岗位职责
2013/12/27 职场文书
4s店总经理岗位职责
2013/12/31 职场文书
C++程序员求职信
2014/05/07 职场文书
计算机网络专业求职信
2014/06/05 职场文书
2015年财务经理工作总结
2015/05/13 职场文书
大学毕业典礼致辞
2015/07/29 职场文书
Python编程编写完善的命令行工具
2021/09/15 Python