python下multiprocessing和gevent的组合使用

对于有些人来说Gevent和multiprocessing组合在一起使用算是个又高大上又奇葩的工作模式.

Python的多线程受制于GIL全局锁的特性,Gevent身为协程也是线程的一种,只是io调度上自己说了算而已。

那么如何使用多个cpu核心? 可以利用多进程mutliprocessing来进行多核并行工作,在多进程里面使用gevent协程框架可以更好的做io调度,相比线程来说减少了无谓的上下文切换.

废话少说,直接上个例子.  下面是多进程下生产者消费者的工作模式,代码本身很简单,自己跑一下就知道怎么一回事了.

  1. # blog: xiaorui.cc
  2.  
  3. from multiprocessing import Process, cpu_count, Queue, JoinableQueue
  4. from gevent import monkey;
  5.  
  6. monkey.patch_all();
  7. import gevent
  8. import datetime
  9. from Queue import Empty
  10.  
  11. class Consumer(object):
  12. def __init__(self, q, no_tasks, name):
  13. self._no_tasks = no_tasks
  14. self._queue = q
  15. self.name = name
  16. self._rungevent(self._queue, self._no_tasks)
  17.  
  18. def _rungevent(self, q, no_tasks):
  19. jobs = [gevent.spawn(self._printq) for x in xrange(no_tasks)]
  20. gevent.joinall(jobs)
  21.  
  22. def _printq(self):
  23. while 1:
  24. value = self._queue.get()
  25. if value is None:
  26. self._queue.task_done()
  27. break
  28. else:
  29. print("{0} time: {1}, value: {2}".format(self.name, \
  30. datetime.datetime.now(), value))
  31. return
  32.  
  33. class Producer(object):
  34. def __init__(self, q, no_tasks, name, consumers_tasks):
  35. print(name)
  36. self._q = q
  37. self._no_tasks = no_tasks
  38. self.name = name
  39. self.consumer_tasks = consumers_tasks
  40. self._rungevent()
  41.  
  42. def _rungevent(self):
  43. jobs = [gevent.spawn(self.produce) for x in xrange(self._no_tasks)]
  44. gevent.joinall(jobs)
  45. for x in xrange(self.consumer_tasks):
  46. self._q.put_nowait(None)
  47. self._q.close()
  48.  
  49. def produce(self):
  50. for no in xrange(100):
  51. print no
  52. self._q.put(no, block=False)
  53. return
  54.  
  55. def main():
  56. total_cores = cpu_count()
  57. total_processes = total_cores * 2
  58. q = JoinableQueue()
  59. print("Gevent on top multiprocessing with 17 gevent coroutines 10 producers gevent and 7 consumers gevent")
  60. producer_gevents = 10
  61. consumer_gevents = 7
  62. jobs = []
  63. start = datetime.datetime.now()
  64. for x in xrange(total_processes):
  65. if not x % 2:
  66. p = Process(target=Producer, args=(q, producer_gevents, "producer %d" % x, consumer_gevents))
  67. p.start()
  68. jobs.append(p)
  69. else:
  70. p = Process(target=Consumer, args=(q, consumer_gevents, "consumer %d" % x))
  71. p.start()
  72. jobs.append(p)
  73.  
  74. for job in jobs:
  75. job.join()
  76.  
  77. print("{0} process with {1} producer gevents and {2} consumer gevents took{3}\
  78. seconds to produce {4} numbers and consume".format(total_processes, \
  79. producer_gevents * total_cores,
  80. consumer_gevents * total_cores, \
  81. datetime.datetime.now() - start,
  82. producer_gevents * total_cores * 100))
  83.  
  84. if __name__ == '__main__':
  85. main()

test

python下multiprocessing和gevent的组合使用的更多相关文章

  1. python3下multiprocessing、threading和gevent性能对比----暨进程池、线程池和协程池性能对比

    python3下multiprocessing.threading和gevent性能对比----暨进程池.线程池和协程池性能对比   标签: python3 / 线程池 / multiprocessi ...

  2. python 协程库gevent学习--gevent数据结构及实战(三)

    gevent学习系列第三章,前面两章分析了大量常用几个函数的源码以及实现原理.这一章重点偏向实战了,按照官方给出的gevent学习指南,我将依次分析官方给出的7个数据结构.以及给出几个相应使用他们的例 ...

  3. python中multiprocessing.pool函数介绍_正在拉磨_新浪博客

    python中multiprocessing.pool函数介绍_正在拉磨_新浪博客     python中multiprocessing.pool函数介绍    (2010-06-10 03:46:5 ...

  4. python的multiprocessing模块进程创建、资源回收-Process,Pool

    python的multiprocessing有两种创建进程的方式,每种创建方式和进程资源的回收都不太相同,下面分别针对Process,Pool及系统自带的fork三种进程分析. 1.方式一:fork( ...

  5. Python下划线简介

    Python中下划线的5种含义 分享一篇文章:The Meaning of Underscores in Python. 本文介绍了Python中单下划线和双下划线("dunder" ...

  6. python下划线的5种含义

    本文介绍了Python中单下划线和双下划线("dunder")的各种含义和命名约定,名称修饰(name mangling)的工作原理,以及它如何影响你自己的Python类. 单下划 ...

  7. python之multiprocessing创建进程

    python的multiprocessing模块是用来创建多进程的,下面对multiprocessing总结一下使用记录. multiprocessing创建多进程在windows和linux系统下的 ...

  8. python并发编程之gevent协程(四)

    协程的含义就不再提,在py2和py3的早期版本中,python协程的主流实现方法是使用gevent模块.由于协程对于操作系统是无感知的,所以其切换需要程序员自己去完成. 系列文章 python并发编程 ...

  9. python 使用multiprocessing需要注意的问题

    我们在编写程序的时候经常喜欢这样写代码 import MySQLdb import time from multiprocessing import Process conn = MySQLdb.co ...

随机推荐

  1. python自定义ORM并操作数据库

    看这个代码之前先去看上篇文章,理解type的用法及元类的含义: ORM可以代替pymysql,实现将python语义装换为sql语句,简单化 import pymysql ''' metaclass, ...

  2. Python统计字符出现次数(Counter包)以及txt文件写入

    # -*- coding: utf-8 -*- #spyder (python 3.7) 1. 统计字符(可以在jieba分词之后使用) from collections import Counter ...

  3. 详解Linux磁盘管理与文件系统

    磁盘基础 硬盘结构 物理结构 盘片:硬盘有多个盘片,每盘片 2 面. 磁头:每面一个磁头. 数据结构 扇区:磁盘上的每个磁道被等分为若干个弧段,这些弧段便是硬盘的扇区. 硬盘的第一个扇区,叫做引导扇区 ...

  4. python学习之模块导入,操作邮件,redis

    python基础学习06 模块导入 导入模块的顺序 1.先从当前目录下找 2.当前目录下找不到,再从环境变量中找,如果在同时在当前目录和环境变量中建立相同的py文件,优先使用当前目录下的 导入模块的实 ...

  5. 文件读写(二)利用SteamReader和StreamWrite类处理字符串、FileSystemWatcher、BinaryReader/BinaryWriter

    一.读写类: TextReader/TextWriter:文本读写,抽象类 TextReader,其派生类: StreamReader:以一种特定的编码从字节流中读取字符. StringReader: ...

  6. Prometheus+Grafana监控

    什么是Prometheus? Prometheus是由SoundCloud开发的开源监控报警系统和时序列数据库(TSDB).Prometheus使用Go语言开发,是Google BorgMon监控系统 ...

  7. SCPI 语言简介

    电子负载中需要用到,所以记录下.来源是德科技 SCPI(可编程仪器的标准命令)是一种基于 ASCII 的仪器编程语言,供测试和测量仪器使用. SCPI 命令采用分层结构,也称为树系统. 相关命令归组于 ...

  8. python类内置方法之__call__

    在python中自定义类时,如果该类实现了一个特殊方法__call__(),那么该类的实例则变成一个可调用的实例对象 如下 In [1]: class A():# 自定义一个A ...: def __ ...

  9. 作业调度系统PBS(Torque)的设置

    1.修改/var/spool/torque/server_priv/目录下的nodes文件 Node1 np=16 gpus=4 Node2 np=16 gpus=4 ... 其中Node1为计算节点 ...

  10. MySQL高级 之 explain执行计划详解(转)

    使用explain关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的,分析你的查询语句或是表结构的性能瓶颈. explain执行计划包含的信息 其中最重要的字段为:i ...