起因:近期须要从hbase中向 ES中导一批数据。使用multiprocessing 启动多个程序同一时候向ES导数据。能够大大提高效率。由于导数的任务是能够依照时间切割的。

一段简单的代码例如以下:

from multiprocessing import Pool

def f(x):
return x*x if __name__ == '__main__':
pool = Pool(processes=4) # start 4 worker processes result = pool.apply_async(f, (10,)) # evaluate "f(10)" asynchronously
print result.get(timeout=1) # prints "100" unless your computer is *very* slow print pool.map(f, range(10))

令我十分不解的,multiprocessing 是怎样实现任务的分发,以及结果的回传的。

我希望可以把它的实现机制与操作系统的进程机制相应起来。

经过阅读代码。得出的结论例如以下:

1. 父进程作为整个任务的分发器,每一个worker是一个子进程

2. 子进程和父进程之间通过管道通讯。包含任务的分发和结果的回传(2个【管道】) ,管道通过【信号量】加锁

以下罗列部分核心代码,增加我自己的凝视,方便大家阅读代码时參考:

1. 管道的创建

    def _setup_queues(self):
from .queues import SimpleQueue
self._inqueue = SimpleQueue() # 管道1 用于分发任务
self._outqueue = SimpleQueue() # 管道2 用于推送结果
self._quick_put = self._inqueue._writer.send
self._quick_get = self._outqueue._reader.recv

再查看 SimpleQueue

class SimpleQueue(object):

    def __init__(self):
self._reader, self._writer = Pipe(duplex=False)
self._rlock = Lock()
if sys.platform == 'win32':
self._wlock = None
else:
self._wlock = Lock()
self._make_methods()

在查看 Pipe

def Pipe(duplex=True):
'''
Returns two connection object connected by a pipe
'''
from multiprocessing.connection import Pipe
return Pipe(duplex)
if sys.platform != 'win32':

    def Pipe(duplex=True):  # duplex 是否是全双工
'''
Returns pair of connection objects at either end of a pipe
'''
if duplex:
s1, s2 = socket.socketpair()
s1.setblocking(True)
s2.setblocking(True)
c1 = _multiprocessing.Connection(os.dup(s1.fileno()))
c2 = _multiprocessing.Connection(os.dup(s2.fileno()))
s1.close()
s2.close()
else:
fd1, fd2 = os.pipe()
c1 = _multiprocessing.Connection(fd1, writable=False)
c2 = _multiprocessing.Connection(fd2, readable=False) return c1, c2

很常使用意思的是。假设是全双工的话。直接用socket 来实现

SimpleQueue 是加过锁的,能够用于多进程间并发读写,来看看锁的实现

class Lock(SemLock):  # 到这里python 代码已经无法再跳入。SemLock 引自 _multiprocessing.so 

    def __init__(self):
SemLock.__init__(self, SEMAPHORE, 1, 1

由SemLock 能够判断,锁就是通过信号量实现的。

2. worker的创建

    def _repopulate_pool(self):
"""Bring the number of pool processes up to the specified number,
for use after reaping workers which have exited.
"""
for i in range(self._processes - len(self._pool)):
w = self.Process(target=worker,
args=(self._inqueue, self._outqueue, # 管道作为參数被传入
self._initializer,
self._initargs, self._maxtasksperchild)
)
self._pool.append(w)
w.name = w.name.replace('Process', 'PoolWorker')
w.daemon = True
w.start()
debug('added worker')
def worker(inqueue, outqueue, initializer=None, initargs=(), maxtasks=None):
assert maxtasks is None or (type(maxtasks) == int and maxtasks > 0)
put = outqueue.put # ***留意这里***
get = inqueue.get # ***留意这里*** # 省略部分代码
completed = 0
while maxtasks is None or (maxtasks and completed < maxtasks):
try:
task = get() # ***留意这里*** 任务是子进程自己从【管道】中取回的,这里的管道相当于消息队列了
except (EOFError, IOError):
debug('worker got EOFError or IOError -- exiting')
break if task is None: # 假设任务是None worker就退出了
debug('worker got sentinel -- exiting')
break job, i, func, args, kwds = task
try:
result = (True, func(*args, **kwds))
except Exception, e:
result = (False, e)
try:
put((job, i, result)) # ***留意这里*** 结果推回队列
except Exception as e:
wrapped = MaybeEncodingError(e, result[1])
debug("Possible encoding error while sending result: %s" % (
wrapped))
put((job, i, (False, wrapped)))
completed += 1
debug('worker exiting after %d tasks' % completed

明确了这些对于multiprocessing 的使用,我明显就有了底气

关于multiprocessing,我也来聊几句的更多相关文章

  1. MySQL优化聊两句

    原文地址:http://www.cnblogs.com/verrion/p/mysql_optimised.html MySQL优化聊两句 MySQL不多介绍,今天聊两句该如何优化以及从哪些方面入手, ...

  2. 聊两句XSS(跨站脚本攻击)

    XSS(跨站脚本攻击),聊两句,五毛的. XSS的危害: 窃取Cookie,盗用用户身份信息 这玩意儿是大多数XSS的目标,也好解决,可以先治个标,直接设置HttpOnly=true ,即不允许客户端 ...

  3. MySQL优化篇(一),我可以和面试官多聊几句吗?——SQL优化流程与优化数据库对象

    我可以和面试官多聊几句吗?只是想偷点技能过来.MySQL优化篇(基于MySQL8.0测试验证),上部分:优化SQL语句.数据库对象,MyISAM表锁和InnoDB锁问题. MyISAM表锁和InnoD ...

  4. 「标准」的 JS风格

    首先,这份 JS风格指南已经在我司的前端团队实行半年多了: 其次,在程序员的世界里,从入行到资深都需要面对几个世界级的难题,如: 世界上最好的编辑器是什么? 是用空格还是 TAB?用空格还特么衍生出 ...

  5. Nginx最大客户连接数算法一些遐想

    Nginx最大客户连接数算法一些遐想 现在很多互联网公司都在使用nginx,并且替换掉以前的Apache,nginx的优点就不说了,浅聊两句nginx的某些配置参数,找到这些参数设置的目的和关联性,并 ...

  6. Atitit.ide技术原理与实践attilax总结

    Atitit.ide技术原理与实践attilax总结 1.1. 语法着色1 1.2. 智能提示1 1.3. 类成员outline..func list1 1.4. 类型推导(type inferenc ...

  7. IT培训行业揭秘(五)

    前面说了一大堆,简单揭露了一些目前培训行业鱼龙混在的情况,那么今天我就站在一个即将毕业的大学生角度来谈谈如何选择一个靠谱的培训机构. 你即将大学毕业了,在大学里面浑浑噩噩的混了几年,马上就要离开校园, ...

  8. Launch和Shut Off操作详解 - 每天5分钟玩转 OpenStack(30)

    本节详细分析 instance launch 和 shut off 操作,以及如何在日志中快速定位有用信息的技巧. Launch Launch instance 应该算 Nova 最重要的操作. 仔细 ...

  9. [No00007F]2016-面经[下] 英文简历写作技巧

    一.简历种类 1.中式 中式简历中,常包括政治面貌,性格及身高体重等.如果中英文简历一起递交,建议中文不写政治面貌,因为如果去外企工作,背景中的政治色彩越少越好,起码没有必要让老外知道. 性格是一个主 ...

随机推荐

  1. OpenJDK源码研究笔记(九)-可恨却又可亲的的异常(NullPointerException)

    可恨的异常 程序开发过程中,最讨厌异常了. 异常代表着程序出了问题,一旦出现,控制台会出现一屏又一屏的堆栈错误信息. 看着就让人心烦. 对于一个新人来讲,遇到异常经常会压力大,手忙脚乱,心生畏惧. 可 ...

  2. Android如何从外部跳进App

    博客出自:http://blog.csdn.net/liuxian13183,转载注明出处! All Rights Reserved ! 这个问题解决了两天时间,因为网上没有完整的解决方案,解决后分享 ...

  3. 网络载入数据和解析JSON格式数据案例之空气质量监測应用

    一.创建一个新的项目 activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res ...

  4. 【POJ 2195】 Going Home(KM算法求最小权匹配)

    [POJ 2195] Going Home(KM算法求最小权匹配) Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submiss ...

  5. FPGA design flow

    FPGA engineering process usually involves the following stages: Architecture design. This stage invo ...

  6. Install the IIS 6.0 Management Compatibility Components in Windows 7 or in Windows Vista from Control Panel

    https://technet.microsoft.com/en-us/library/bb397374(v=exchg.80).aspx Install the IIS 6.0 Management ...

  7. spring-cloud导入eclipse时,@slf4j注解为什么找不到log变量

    原因是缺少插件Lomboz. Lomboz是一个基于LGPL的开源J2EE综合开发环境的Eclipse插件,对编码,发布,测试,以及debug等各个软件开发的生命周期提供支持,支持JSP,EJB等.L ...

  8. oracle中查询表的信息,包括表名,字段名,字段类型,主键,外键唯一性约束信息

    来源于网上整理 总结了一下oracle中查询表的信息,包括表名,字段名,字段类型,主键,外键唯一性约束信息,索引信息查询SQL如下,希望对大家有所帮助: 1.查询出所有的用户表select * fro ...

  9. 使用iVMS-4200 存储录像数据时的设置

    1.安装软件时,选择:存储服务器 2.对存储服务器进行配置,具体配置见 配置手册.

  10. Linux 如何重新划分Swap交换分区

    SWAP分区是LINUX暂时存储数据的交换分区,它主要是把主内存上暂时不用得数据存起来,在需要的时候再调进内存内,且作为SWAP使用的分区不用指定“MoutPoint”(载入点)它至少要等于系统上实际 ...