python进程process类返回值_如何从Process或Thread实例返回值?

本文介绍了如何在Python的多进程和多线程环境中使用multiprocessing.Queue、multiprocessing.Pipe及queue.Queue进行进程间、线程间通信,通过示例展示了如何将结果从子进程或线程传回父进程。强调了在不同场景下选择合适通信方式的重要性。
摘要由CSDN通过智能技术生成

您将需要一个multiprocessing.Pipe或multiprocessing.Queue将结果发送回您的父进程.如果你只做I / 0,你应该使用Thread而不是Process,因为它更轻巧,大部分时间花在等待上.我告诉你一般来说Process和Threads是如何完成的.

处理队列

多处理队列构建在管道之上,访问与锁/信号量同步.队列是线程和进程安全的,这意味着您可以将一个队列用于多个生产者/消费者进程,甚至可以在这些进程中使用多个线程.添加队列中的第一个项目也将在调用进程中启动馈送器线程. multiprocessing.Queue的额外开销使得使用管道为单生产者/单一消费者场景更好,更高性能.

以下是使用multiprocessing.Queue发送和检索结果的方法:

from multiprocessing import Process, Queue

SENTINEL = 'SENTINEL'

def sim_busy(out_queue, x):

for _ in range(int(x)):

assert 1 == 1

result = x

out_queue.put(result)

# If all results are enqueued, send a sentinel-value to let the parent know

# no more results will come.

out_queue.put(SENTINEL)

if __name__ == '__main__':

out_queue = Queue()

p = Process(target=sim_busy, args=(out_queue, 150e6)) # 150e6 == 150000000.0

p.start()

for result in iter(out_queue.get, SENTINEL): # sentinel breaks the loop

print(result)

队列作为参数传递给函数,结果是队列上的.put()和队列中的父get.()s. .get()是一个阻塞调用,执行不会恢复,直到要获取某些内容(可以指定timeout参数).注意这里的工作sim_busy是cpu密集型的,那就是你在线程上选择进程的时候.

过程&管

对于一对一连接,管道就足够了.设置几乎相同,只是方法命名不同,并且对Pipe()的调用返回两个连接对象.在双工模式下,两个对象都是读写结束,duplex = False(单工)第一个连接对象是管道的读端,第二个是写端.在这个基本场景中,我们只需要一个simplex-pipe:

from multiprocessing import Process, Pipe

SENTINEL = 'SENTINEL'

def sim_busy(write_conn, x):

for _ in range(int(x)):

assert 1 == 1

result = x

write_conn.send(result)

# If all results are send, send a sentinel-value to let the parent know

# no more results will come.

write_conn.send(SENTINEL)

if __name__ == '__main__':

# duplex=False because we just need one-way communication in this case.

read_conn, write_conn = Pipe(duplex=False)

p = Process(target=sim_busy, args=(write_conn, 150e6)) # 150e6 == 150000000.0

p.start()

for result in iter(read_conn.recv, SENTINEL): # sentinel breaks the loop

print(result)

线程&队列

要与线程一起使用,您需要切换到queue.Queue. queue.Queue构建在collections.deque之上,添加一些锁以使其成为线程安全的.与多处理的队列和管道不同,放在队列上的对象.Queue不会被腌制.由于线程共享相同的内存地址空间,因此不需要进行内存复制的序列化,只传输指针.

from threading import Thread

from queue import Queue

import time

SENTINEL = 'SENTINEL'

def sim_io(out_queue, query):

time.sleep(1)

result = query + '_result'

out_queue.put(result)

# If all results are enqueued, send a sentinel-value to let the parent know

# no more results will come.

out_queue.put(SENTINEL)

if __name__ == '__main__':

out_queue = Queue()

p = Thread(target=sim_io, args=(out_queue, 'my_query'))

p.start()

for result in iter(out_queue.get, SENTINEL): # sentinel-value breaks the loop

print(result)

>阅读here为什么结果在iter(out_queue.get,SENTINEL):

应尽可能优先选择True … break设置.

>阅读here为什么你应该在所有脚本中使用if __name__ ==’__ main__’:特别是在多处理中.

>更多关于get() – 用法here.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值