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. 为RecyclerView的item之间设置相同的间距

    项目中经常碰到列表当中的每一项之间需要设置间距的问题,我们可以通过给列表中的每一项设置margin值来实现,例如纵向的间距可以给每一项设置right_margin,这种方法下,整个列表的最左边会紧贴屏 ...

  2. Nginx 常用配置整理

    #定义Nginx运行的用户和用户组 user www www; #nginx进程数,建议设置为等于CPU总核心数. worker_processes 8; #全局错误日志定义类型,[ debug | ...

  3. Lamp环境搭建Linux CentOS6.5编译安装mysql5.6

    经典web开发组合Lamp环境搭建之mysql安装详解 安装前准备 通过rpm命令检查centos上是否已经安装mysql,然后卸载已经存在的mysql版本 [root@localhost src]# ...

  4. hdu4681 String DP(2013多校第8场)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4681 思路: 我是胡搞过的 就是先预处理出(i,j)的正向的最大连续子串和逆向最大连续子串 然后对于A ...

  5. RabbitMQ学习-1

    转载自:http://blog.csdn.net/anzhsoft/article/details/19563091. 1. 历史 RabbitMQ是一个由erlang开发的AMQP(Advanced ...

  6. Hibernate 核心接口和工作机制

    主要内容 Configuration类 sessionFactory接口 session接口 Transaction接口 Query 和 criteria接口 1.Configuration类 负责管 ...

  7. vuex使用报错

    1.vuex简介 最近在玩vuex,不得不说它是一个很强大的工具,它的目的就是把数据统一管理起来,方便各个组件之间来回调用 2.vuex引用报错 当我们去官网看API文档的时候,会发现官网是这么应用a ...

  8. ztree实现权限功能(横向显示)

    最近在做权限功能的时候,采用的ztree实现的,但是产品要求最后一层的权限节点要横向显示.开始在网上找的解决方案是用css样式把最后一层的display设置为inline.在我本地电脑上看了下.效果不 ...

  9. Vmware报错:此主机支持IntelVTx 但IntelVTx处于禁用状态

    "此主机支持IntelVTx 但IntelVTx处于禁用状态",报错原因:电脑未开启虚拟化 解决方案: 电脑关机(是关机不是重启)--开机,进BIOS --选择 configura ...

  10. C语言socket编程——linux环境

    先写一个服务器端的监听程序,功能室从客户端读取字符,接收到后告知客户端“I got your message: ”+收到的消息:server.c #include <stdio.h> #i ...