multiprocessing的用法、进程通信

记录multiprocessing的基本用法以及如何利用Queue进行进程间的通信

一个很简单的例子

from multiprocessing import Process
import multiprocessing as mp


# 每个进程要把y放入队列后,再放入一个'@'表示进程结束
def function_to_run(name, w, r):
    y = w + 1
    r.put(y)
    r.put('@')
    print('Hello', name, y)


if __name__ == '__main__':
    rr = mp.Queue()
    processes = []
    scores = []

    for i in range(5):  # 创建5个进程
        p = Process(target=function_to_run, args=(f'World {i}', i, rr))  # 创建一个进程对象
        p.start()  # 启动进程
        processes.append(p)  # 将进程对象添加到列表中

    for p in processes:   # 等待所有进程结束
        p.join()
	
	# 从队列取出之前放入的元素
	# 注意:队列先存先取,取完即没
    while not rr.empty():   # 如果队列不为空,则。。。
        q = rr.get()
        scores.append(q)

    print("--------------- 主程序 ---------------")
    print(scores)

输出为:

Hello World 0 1
Hello World 2 3
Hello World 3 4
HelloHello  World 4 5
World 1 2
--------------- 主程序 ---------------
[1, '@', 3, '@', 4, '@', 5, 2, '@', '@']

你会发现,输出结果并不是我们想象的那样:数组中一个数字一个’@‘,这样排列。
这是因为这5个进程并行运行,结果存入队列rr时,总的结果会由于进程先后存入。
比如:a进程向队列rr存入2,马上要存’@'时,b进程向队列rr存入1,这就导致显示为:[2, 1, '@']

利用get_lock()

锁对象可以用于同步进程,以避免多个进程同时访问或修改共享资源,从而可能导致数据不一致或其他并发问题。如果锁已经被另一个进程获取,那么这个进程就会被阻塞,直到锁被释放。

from multiprocessing import Process
import multiprocessing as mp


def function_to_run(name, w, e, r):
	# w被某个进程锁定时,其他进程阻塞,等待
    with w.get_lock():
        y = w.value + e
        r.put(y)
        r.put('@')
    print('Hello', name, y)


if __name__ == '__main__':
	# 创建一个共享对象ww
    ww = mp.Value('d', 0)  # 'd' 表示浮点数类型
    rr = mp.Queue()
    rr.put('start')

    processes = []
    scores = []

    for ee in range(5):  # 创建5个进程
        p = Process(target=function_to_run, args=(f'World {ee}', ww, ee, rr))  # 创建一个进程对象
        p.start()  # 启动进程
        processes.append(p)  # 将进程对象添加到列表中

    for p in processes:   # 等待所有进程结束
        p.join()

    while not rr.empty():
        q = rr.get()
        scores.append(q)

    print(scores)

输出为:

Hello World 0 0.0
Hello World 1 1.0
Hello World 2 2.0
Hello World 4 4.0
Hello World 3 3.0
['start', 0.0, '@', 1.0, '@', 2.0, '@', 4.0, '@', 3.0, '@']

在主进程中谨慎使用 put()

运行以下程序:

import multiprocessing as mp


if __name__ == '__main__':

    scores = []
    sa = []
    rr = mp.Queue()

    rr.put('start')
    rr.put(None)
    rr.put('qq')

    while not rr.empty():
        q = rr.get()
        scores.append(q)

    print(scores)

    while not rr.empty():
        x = rr.get()
        sa.append(x)

    print(sa)

多运行几次你会发现:有以下几种情况。

['start', None, 'qq']
[]

或者

['start', None]
['qq']

或者

['start']
[None, 'qq']

或者

[]
['start', None, 'qq']

总结:使用多线程时注意使用锁,保证安全

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值