Python3 进程multiprocessing的基本用法

本文深入讲解了Python中使用multiprocessing包进行多进程编程的方法,包括基本用法、进程间通信手段如Queue、Pipe和Manager,以及进程同步和进程池的运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

进程的基本用法: 

multiprocessing是一个使用类似于线程模块的API支持产生进程的包。 多处理包提供本地和远程并发,通过使用子进程而不是线程有效地侧向执行全局解释器锁。 因此,多处理模块允许程序员充分利用给定机器上的多个处理器。 它可以在Unix和Windows上运行。

import multiprocessing
import time


def f(name):
    time.sleep(2)
    print('hello', name)


if __name__ == '__main__':
    p = multiprocessing.Process(target=f, args=('bob',))
    p.start()
    p.join()

进程间的通信:

不同进程由于内存不是共享的,如果想要实现不同进程之间的数据交换,可以用以下方法:

Queues:

使用的方式和threading里得queue差不多,需要注意的是:这里的Queue是进程里得队列,而不是线程里面的

from multiprocessing import Process, Queue
# import queue  这是进程里面的queue

def f(q):
    q.put([42, None, 'hello'])
if __name__ == '__main__':
    q = Queue()
    # q.put([42, None, 'hello'])
    p = Process(target=f,args=(q,))
    p.start()
    print(q.get())  # prints "[42, None, 'hello']"
    p.join()
运行结果:
[42, None, 'hello']

Pipes:

Pipe()函数返回一个由管道连接的连接对象,默认情况下是双工(双向)。

from multiprocessing import Process, Pipe


def f(conn):
    conn.send("发送给parent")
    print("child receive:", conn.recv())
    conn.close()


if __name__ == '__main__':
    parent_conn, child_conn = Pipe() # 创建父管道和子管道
    p = Process(target=f, args=(child_conn,))
    p.start()
    print("parent receive:",parent_conn.recv())
    parent_conn.send("发送给child")
    parent_conn.close()
    p.join()
运行结果:
parent receive: 发送给parent
child receive: 发送给child

Manages:

Manager()返回的管理器对象控制一个服务器进程,该进程保存Python对象并允许其他进程使用代理操作它们。Manager()返回的管理器将支持类型列表,dict,Namespace,Lock,RLock,Semaphore,BoundedSemaphore,Condition,Event,Barrier,Queue,Value和Array。 例如:

from multiprocessing import Process, Manager
import os

def f(d, l):
    d[1] = 'Python'
    d[2] = "Java"
    d[3] = "C++"
    l.append(os.getpid()) # 在I中添加进程号,os.getpid()获得当前的进程号
    print(l)


if __name__ == '__main__':
    with Manager() as manager:
        d = manager.dict() # 创建一个字典
        l = manager.list(range(5)) # 创建一个列表
        p_list = [] # 创建一个空列表存放进程
        for i in range(3):
            p = Process(target=f, args=(d, l))
            p.start()
            p_list.append(p)
        for res in p_list:
            res.join()
        print(d)
        print(l)
运行结果:
[0, 1, 2, 3, 4, 47940]
[0, 1, 2, 3, 4, 47940, 23300]
[0, 1, 2, 3, 4, 47940, 23300, 19108]
{1: 'Python', 2: 'Java', 3: 'C++'}
[0, 1, 2, 3, 4, 47940, 23300, 19108]

进程同步:

通过进程锁开启多个进程,用法和线程锁相似。

from multiprocessing import Process, Lock
import os
def f(l, i):
    l.acquire()  # 获得进程锁
    try:
        print('Running process:', i, os.getpid())
    finally:
        l.release() # 释放进程锁

if __name__ == '__main__':
    lock = Lock() # 实例化一个进程锁
    for num in range(3):
        Process(target=f, args=(lock, num)).start()
运行结果:
Running process: 0 51016
Running process: 1 43240
Running process: 2 50932

进程池:

进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进程,那么程序就会等待,直到进程池中有可用进程为止,与线程里面的信息量相似。进程池中有两个方法:

  • apply
  • apply_async
from multiprocessing import Process, Pool,freeze_support
import time, os


def Foo(i):
    time.sleep(2)
    print("in process:", os.getpid())
    return i + 100


def Bar(arg):
    print('-->exec done:', arg)


if __name__ == '__main__':

    # freeze_support()
    print("dsd")
    pool = Pool(5) # 允许进程池里同时放入5个进程

    for i in range(10):
         pool.apply_async(func=Foo, args=(i,), callback=Bar) # 并行,callback=回调,执行完func之后,再回来执行callback
         # pool.apply(func=Foo, args=(i,)) # 进程串行

    print('end')
    pool.close()
    pool.join()  # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。

#apply_async运行结果:
dsd
end
in process: 49788
-->exec done: 100
in process: 48364
-->exec done: 101
in process: 49964
-->exec done: 102
in process: 48048
-->exec done: 103
in process: 49580
-->exec done: 104
in process: 49788
-->exec done: 105
in process: 48364
-->exec done: 106
in process: 49964
-->exec done: 107
in process: 48048
-->exec done: 108
in process: 49580
-->exec done: 109
#apply运行结果:
dsd
in process: 3988
in process: 48940
in process: 48268
in process: 20156
in process: 42952
in process: 3988
in process: 48940
in process: 48268
in process: 20156
in process: 42952
end

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值