multiprocessing 与 threading.Thread 类似

multiprocessing.Process 创建进程, 该进程可以运行用 python 编写的函数.

multiprocessing.Process.start()
multiprocessing.Process.run()
multiprocessing.Process.join() 

Process.PID 保存有 PID, 如果进程还没有 start() , 则 PID 为 None.

注意

  • 在 UNIX 平台上, 当某一个进程终止之后, 该进程需要被其父进程调用 wait , 否则进程就成为 僵尸进程. 所以, 需要对每个 Process 对象调用 join() 方法(等同于 wait), 对于多线程来说, 由于只有一个进程, 所以不存在次必要性.

  • multiprocessing 提供了 threading 中没有的 IPC (比如 Queue,Pipe), 效率上更高. 应有限考虑 Pipe 和 Queue, 避免使用 Lock/Event/Semaphore/Condition 等同步方式(应为他们占据的不是用户进程的资源).

  • 多进程应该避免共享资源. 在多线程中, 我们可以比较容易的共享资源, 比如使用全局变量或传递参数. 在多进程情况下, 由于每个进程有自己独立的内存空间, 以上方法并不合适. 此时我们可以通过共享内存和 Manager 的方法来共享资源. 但这样做提高了程序的复杂度, 并因为同步的需要而降低了程序的效率.

示例代码
    #!/usr/local/bin/env python
    #

    import os
    import threading
    import multiprocessing

    def worker(sign,lock):
        lock.acquire()
        print(sign,os.getpid())
        lock.release()

    print("main:",os.getpid())

    # multi-thread
    record=[]

    lock = threading.Lock()
    for i in range(5):
        thread = threading.Thread(target=worker,args=('thread',lock))
        thread.start()
        record.append(thread)

    for thread in record:
        thread.join()

    # multi-process
    record = []
    lock = multiprocessing.Lock()

    for i in range(5):
        process = multiprocessing.Process(target=worker,args=('process',lock))
        process.start()
        record.append(process)

    for process in record:
        process.join()

    输出 : 所有 Thread 的 PID 都与主程序相同, 而每个 Process都有一个不同的 PID.

        ('main:', 105748)
        ('thread', 105748)
        ('thread', 105748)
        ('thread', 105748)
        ('thread', 105748)
        ('thread', 105748)
        ('process', 105754)
        ('process', 105756)
        ('process', 105758)
        ('process', 105755)
        ('process', 105757)    

multiprocessing.Lock

multiprocessing.Event

multiprocessing.Semaphore

multiprocessing.Condition

multiprocessing.Pipe()

multiprocessing.Pipe()  # 默认创建双向管道, 该对象返回一个包含两个元素的表, 每个元素代表 Pipe 的一端(Connection对象). 可以在一端调用 send() 方法, 另一端调用 recv() 方法, 实现通信.
multiprocessing.Pipe(duplex=False)    # 创建单向管道
multiprocessing.Pipe().send()
multiprocessing.Pipe().recv()
示例代码:
#!/usr/local/bin/env python
#

import multiprocessing as mul

def proc1(pipe):
    pipe.send('hello')
    print('proc1 rec:',pipe.recv())

def proc2(pipe):
    print('proc2 rec:',pipe.recv())
    pipe.send('hello, too')

# Build a pipe
pipe = mul.Pipe()

# Pass an end of the pipe to process 1
p1   = mul.Process(target=proc1, args=(pipe[0],))
# Pass the other end of the pipe to process 2
p2   = mul.Process(target=proc2, args=(pipe[1],))
p1.start()
p2.start()
p1.join()
p2.join()    

输出:
    ('proc2 rec:', 'hello')
    ('proc1 rec:', 'hello ,too!')

multiprocessing.Queue 是先进先出的结构. Queue 允许多个进程放入, 多个进程从队列取出对象.

mutiprocessing.Queue(maxsize)   创建队列, maxsize 表示队列中可以存放对象的最大数量.

mutiprocessing.Queue(maxsize).put()
mutiprocessing.Queue(maxsize).get()
示例代码
#!/usr/local/bin/env python
#

import os
import multiprocessing
import time

# input worker
def inputQ(queue):
    info = str(os.getpid()) + '(put):' + str(time.time())
    queue.put(info)

# output worker
def outputQ(queue,lock):
    info = queue.get()
    lock.acquire()
    print (str(os.getpid()) + '(get):' + info)
    lock.release()

# Main
record1 = []   # store input processes
record2 = []   # store output processes
lock  = multiprocessing.Lock()    # To prevent messy print
queue = multiprocessing.Queue(3)

# input processes
for i in range(10):
    process = multiprocessing.Process(target=inputQ,args=(queue,))
    process.start()
    record1.append(process)

# output processes
for i in range(10):
    process = multiprocessing.Process(target=outputQ,args=(queue,lock))
    process.start()
    record2.append(process)

for p in record1:
    p.join()

queue.close()  # No more object will come, close the queue

for p in record2:
    p.join()

输出:
    105880(get):105865(put):1488439837.07
    105883(get):105866(put):1488439837.07
    105879(get):105867(put):1488439837.08
    105884(get):105870(put):1488439837.08
    105877(get):105873(put):1488439837.08
    105885(get):105871(put):1488439837.08
    105886(get):105874(put):1488439837.09
    105878(get):105872(put):1488439837.08
    105881(get):105868(put):1488439837.08
    105887(get):105876(put):1488439837.09

multiprocessing.Pool(num) # num 表示创建的进程数.

multiprocessing.Pool(num)       # 创建进程池,
multiprocessing.Pool(num).map()     # 与 map() 函数类似.
multiprocessing.Pool(num).apply_async(func,args)   # 从进程池中取出一个进程执行 func, args 为 func 的参数. 他将返回一个 AsyncResult 的对象, 可以对该对象调用 get() 方法, 获取结果.
multiprocessing.Pool(num).apply_async(func,args).get()
multiprocessing.Pool(num).close()   # 进程池不再创建新的进程
multiprocessing.Pool(num).join()    # wait 进程池的全部进程, 必须对 Pool 先调用 close() 方法, 才能 join.
示例代码:
    import multiprocessing as mul

    def f(x):
        return x**2

    pool = mul.Pool(5)
    rel  = pool.map(f,[1,2,3,4,5,6,7,8,9,10])
    print(rel)

    输出:
        [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

共享内存

multiprocessing.Value(key,value)    # 双精度数数字
multiprocessing.Array(key,value_list)   # 数组
代码示例
import multiprocessing

def f(n, a):
    n.value   = 3.14
    a[0]      = 5

num   = multiprocessing.Value('d', 0.0)
arr   = multiprocessing.Array('i', range(10))

p = multiprocessing.Process(target=f, args=(num, arr))
p.start()
p.join()

print num.value
print arr[:]

输出:
    3.14
    [5, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Manager

s = multiprocessing.Manager()

s.address          s.dict             s.list             s.register        s.Value
s.Array            s.Event            s.Lock             s.RLock
s.BoundedSemaphore s.get_server       s.Namespace        s.Semaphore
s.Condition        s.join             s.Pool             s.shutdown
s.connect          s.JoinableQueue    s.Queue            s.start
代码示例
import multiprocessing

def f(x, arr, l):
    x.value = 3.14
    arr[0] = 5
    l.append('Hello')

server = multiprocessing.Manager()
x    = server.Value('d', 0.0)
arr  = server.Array('i', range(10))
l    = server.list()

proc = multiprocessing.Process(target=f, args=(x, arr, l))
proc.start()
proc.join()

print(x.value)
print(arr)
print(l)

输出结果:
    3.14
    array('i', [5, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    ['Hello']

python 标准库 -- multiprocessing的更多相关文章

  1. python 标准库 —— 线程与同步(threading、multiprocessing)

    1. 创建线程 使用 os 下的 fork() 函数调用(仅限 Unix 系统) import os print('current process (%s) starts ...' % (os.get ...

  2. python标准库00 学习准备

    Python标准库----走马观花 python有一套很有用的标准库.标准库会随着python解释器一起安装在你的电脑上的.它是python的一个组成部分.这些标准库是python为你准备的利器,可以 ...

  3. Python标准库的学习准备

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Python标准库是Python强大的动力所在,我们已经在前文中有所介绍.由于标准 ...

  4. Python标准库——走马观花

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Python有一套很有用的标准库(standard library).标准库会随着 ...

  5. Python标准库概览

    Python标准库通常被称为"自带的电池",自然地提供了广泛的功能,涵盖了大概200个左右的包与模块.不断有高质量的包或模块被开发出来,极大的丰富了标准库.但有些模块放在标准库中很 ...

  6. python第六天 函数 python标准库实例大全

    今天学习第一模块的最后一课课程--函数: python的第一个函数: 1 def func1(): 2 print('第一个函数') 3 return 0 4 func1() 1 同时返回多种类型时, ...

  7. 转--Python标准库之一句话概括

    作者原文链接 想掌握Python标准库,读它的官方文档很重要.本文并非此文档的复制版,而是对每一个库的一句话概括以及它的主要函数,由此用什么库心里就会有数了. 文本处理 string: 提供了字符集: ...

  8. Python 标准库一览(Python进阶学习)

    转自:http://blog.csdn.net/jurbo/article/details/52334345 写这个的起因是,还是因为在做Python challenge的时候,有的时候想解决问题,连 ...

  9. python 标准库大全

    python 标准库 文本 string:通用字符串操作 re:正则表达式操作 difflib:差异计算工具 textwrap:文本填充 unicodedata:Unicode字符数据库 string ...

随机推荐

  1. PHP的虚拟域名的配置

    由于本人的自己搭建的php环境,Wamp环境.虚拟域名是写程序的一个最基本的配置,也对项目的调试有一定的真实感.我在学习虚拟域名的时候是受到了一些的问题,所以说写这个是为了帮助新人少走弯路, 也是为了 ...

  2. 在SOUI中支持高分屏显示

    和手机屏幕一样,高分屏在PC上使用越来越多.传统的桌面程序都是像素为单位进行UI布局,而且是适配传统的96dpi的显示器的.这就导致这些程序在高分屏上显示很小,用户用起来很难受. 虽然windows系 ...

  3. Java数据类型(基本数据类型)学习

    Java数据类型(基本数据类型)学习 与其他语言一样,Java编程同样存在,比如int a,float b等.在学习变量之前我就必须先了解Java的数据类型啦. Java的数据类型包括基本数据类型和引 ...

  4. 基于Struts2,Spring4,Hibernate4框架的系统架构设计与示例系统实现

    笔者在大学中迷迷糊糊地度过了四年的光景,心中有那么一点目标,但总感觉找不到发力的方向. 在四年间,尝试写过代码结构糟糕,没有意义的课程设计,尝试捣鼓过Android开发,尝试探索过软件工程在实际开发中 ...

  5. Visual Lisp获得网络时间的方法

    (defun c:tt (/ ie-obj) (setq ie-obj (vlax-get-or-create-object "Msxml2.xmlhttp")) ) (vlax- ...

  6. Java核心技术 卷I chapter05 继承

    2017年4月10日19:41:44 仅仅用于打好基础 1. 在Java中,所有的继承都是公有继承,而没有C++中的私有继承和保护继承! 2.关键字super的使用方法: (1) 子类中想调用父类中的 ...

  7. 面向对象设计(Object-Oriented Design,OOD)

    前言 OOD简介 Shubho:亲爱的,让我们开始学习OOD吧.你了解面向对象原则吗? Farhana:你是说封装,继承,多态对吗?我知道的. Shubho:好,我希望你已了解如何使用类和对象.今天我 ...

  8. 使用java API操作hdfs--通过filesystem API 来读取数据

    上面的Path的包是导入错误了,nio中的包是抽象类,是无法创建的,所以换地方更改. 修改之后,指定jar包之后,编译成功,如下,并进行文件的读取操作,依然是成功啦:

  9. Xcode8.3.2制作静态库

    1. 打开Xcode8.3.2: 2. 如下操作 3. 创建Bundle文件 比如xib或者图片存放 File-new-Target  选择macOS 搜索Bundle文件 4.创建完成如下所示 5. ...

  10. hdu1255 覆盖的面积 线段树+里离散化求矩形面积的交

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 求矩形面积的交的线段树题目,刚做了求并的题目,再做这个刚觉良好啊,只要再加一个表示覆盖次数大于1 ...