Python 如何在流程之间进行沟通,同时';重新运行
我希望有两个并行运行的进程。一个从另一个获取输入,处理数据,并将处理后的数据作为另一个的输出发送回。另一个过程做同样的事情。显然,需要有一个起点和一个终点 在进程运行时,如何在进程之间进行通信?我只在两个进程之后运行了它们 我试图用Python 如何在流程之间进行沟通,同时';重新运行,python,python-3.x,multiprocessing,Python,Python 3.x,Multiprocessing,我希望有两个并行运行的进程。一个从另一个获取输入,处理数据,并将处理后的数据作为另一个的输出发送回。另一个过程做同样的事情。显然,需要有一个起点和一个终点 在进程运行时,如何在进程之间进行通信?我只在两个进程之后运行了它们 我试图用多处理来解决这个问题: from multiprocessing import Process, Queue, Array sentinel = -1 def process1(q, arr): # Receives data, modifies it an
多处理来解决这个问题:
from multiprocessing import Process, Queue, Array
sentinel = -1
def process1(q, arr):
# Receives data, modifies it and sends it back
while True:
data = q.get() # Receive data
if data is sentinel:
break
data *= 2 # Data modification
arr.append(data) # Data logging
q.put(data) # Send data
q.put(sentinel) # Send end signal
def process2(q, arr):
# Receives data, increments it and sends data back
if q.empty():
data = 1
else:
while True:
data = q.get() # Receive data
if data == sentinel:
break
data += 1
q.put(data) # Send data
arr.append(data) # Data logging
q.put(sentinel) # Send end signal
if __name__ == "__main__":
q = Queue()
logbook = Array('i', 0)
counter = 0
while counter < 10:
process_1 = Process(target=process1, args=(q, logbook))
process_2 = Process(target=process2, args=(q, logbook))
process_1.start()
process_2.start()
q.close()
q.join_thread()
process_1.join()
process_2.join()
counter += 1
print(logbook)
来自多处理导入进程、队列、数组的
哨兵=-1
def进程1(q、arr):
#接收数据、修改数据并将其发送回
尽管如此:
data=q.get()#接收数据
如果数据是sentinel:
打破
数据*=2#数据修改
arr.append(数据)#数据记录
q、 放置(数据)#发送数据
q、 put(哨兵)#发送结束信号
def进程2(q、arr):
#接收数据、增加数据并将数据发送回
如果q.empty():
数据=1
其他:
尽管如此:
data=q.get()#接收数据
如果数据==哨兵:
打破
数据+=1
q、 放置(数据)#发送数据
arr.append(数据)#数据记录
q、 put(哨兵)#发送结束信号
如果名称=“\uuuuu main\uuuuuuuu”:
q=队列()
日志=数组('i',0)
计数器=0
当计数器<10时:
过程1=过程(目标=过程1,参数=(q,日志))
过程2=过程(目标=过程2,参数=(q,日志))
进程_1.start()
进程2.start()
q、 关闭()
q、 连接线程()
进程1.join()
进程2.join()
计数器+=1
打印(日志)
您可以使用套接字来完成此任务,甚至可以使用微服务方法(例如,通过rest api调用)。我试图理解您的需求,但我并不完全清楚,因此我建议使用此代码的生产者-消费者版本,在该版本中,两个进程进行通信,以在一定数量的迭代中达到最终结果
首先,您需要两个队列,以避免将内容放入队列的同一进程在另一个队列之前读取内容。
其次,您需要一种机制来在计算结束时达成一致,在本例中是一条None消息
我提出的解决方案总结在以下代码中:
from multiprocessing import Process, Queue, Array
def process1(in_queue, out_queue):
# Receives data, modifies it and sends it back
while True:
data = in_queue.get() # Receive data
if data is None:
out_queue.put(None) # send feedback about END message
out_queue.close()
out_queue.join_thread()
break
data *= 2 # Data modification
out_queue.put(data) # Send data
def process2(in_queue, out_queue, how_many):
data = 0
# Receives data, increments it and sends data back
while how_many > 0:
data += 1 # Data modification
out_queue.put(data) # Send data
how_many -= 1
data = in_queue.get() # Receive data
if data is None:
break
# send END message
out_queue.put(None)
out_queue.close()
out_queue.join_thread()
assert in_queue.get() is None
if __name__ == "__main__":
q1 = Queue()
q2 = Queue()
process_1 = Process(target=process1, args=(q1, q2))
process_2 = Process(target=process2, args=(q2, q1, 10))
process_1.start()
process_2.start()
process_2.join()
process_1.join()
q1.close()
q2.close()
q1.join_thread()
q2.join_thread()
@罗伯托·特拉尼
从您的解决方案开始,我甚至能够使用第三个队列记录两个进程之间的通信
谢谢你,我真的被卡住了,不知道如何解决这个问题
from multiprocessing import Process, Queue
def process1(in_queue, out_queue, log_queue):
# Receives data, modifies it and sends it back
while True:
data = in_queue.get() # Receive data
if data is None:
log_queue.put(None) # log END
out_queue.put(None) # send feedback about END message
break
data *= 2 # Data modification
print("p1: {}".format(data))
log_queue.put(data) # Log data
out_queue.put(data) # Send data
def process2(in_queue, out_queue, how_many, log_queue):
data = 0
# Receives data, increments it and sends data back
while how_many > 0:
data += 1 # Data modification
print("p2: {}".format(data))
log_queue.put(data) # Log Data
out_queue.put(data) # Send data
how_many -= 1
data = in_queue.get() # Receive data
if data is None:
break
# send END message
log_queue.put(None) # log END
out_queue.put(None)
out_queue.close()
out_queue.join_thread()
assert in_queue.get() is None
if __name__ == "__main__":
q1 = Queue()
q2 = Queue()
q3 = Queue()
logbook = []
process_1 = Process(target=process1, args=(q1, q2, q3))
process_2 = Process(target=process2, args=(q2, q1, 10, q3))
process_1.start()
process_2.start()
process_2.join()
process_1.join()
q1.close()
q2.close()
q1.join_thread()
q2.join_thread()
while True:
data = q3.get()
logbook.append(data)
if data is None:
break
q3.close()
q3.join_thread()
print(logbook)
你能进一步解释一下你所说的微服务方法是什么意思吗?我听说过REST,现在我正试图弄清楚,如何在Python中实现这个范例
例如,像web服务。您可以提供对模块内服务(函数、方法)的访问。可以通过RESTAPI访问该模块,例如使用自顶向下的方法作为OpenApi规范()
Im目前正在使用这种方法:设计高级接口(模块、每个模块的功能、层次结构和模块的互连);在openapi编辑器的yaml/json文件中使用CRUD()写下满足REST端点的设计(在线:);使用编辑器功能生成python代码(flask);编辑锅炉板代码以实际实现后端功能;运行服务器以提供对API方法的访问。
您甚至可以将模块转换为docker映像以实现可扩展性:Im使用此基本映像:RFM?通过使用asyncioplease提供一个示例。您所说的RFM是什么意思?我的意思是但不是进程间通信系统。您能进一步解释一下微服务方法的含义吗?我听说过REST,现在我想弄清楚如何用Python实现这个范例,比如web服务。您可以提供对模块内服务(函数、方法)的访问。这个模块可以通过RESTAPI访问,例如使用自顶向下的方法作为OpenApi规范()。这个解决方案涵盖了我打算做的事情!我没有想过为此使用两个队列。非常感谢。您能否简要解释一下,为什么process1可以在发送结束消息之前退出?是否可以通过使用关键字finally来解决这个问题,这样即使出现错误,也会发送结束消息?@ceske我解决了这个问题,确保调用close
和join
onout\u queue
。问题可能是,当内部线程在队列上写入None消息时,进程退出。确保加入内部线程这种行为不再发生。很乐意提供帮助,欢迎使用堆栈溢出。如果此答案或任何其他答案解决了您的问题,请将其标记为已接受。完成!使用您的解决方案,我甚至可以使用第三个队列记录两个进程之间的通信。感谢您的解释。我可能希望稍后在项目中回到这种方法。现在我的印象是,这对我目前的需要来说太多了。