[英]Python subprocess gets stuck by a child process
I am trying to call a subprocess inside a subprocess in order to send information using ZMQ to an Unity Application. 我试图在子流程中调用一个子流程,以便使用ZMQ将信息发送到Unity应用程序。 When I call socket.recv()
or time.sleep
, it stucks the parent process(which is a child process of a main process) 当我打电话socket.recv()
或time.sleep
,它stucks父进程(这是一个主进程的子进程)
import json
import zmq
from multiprocessing import Process
import multiprocessing as mp
from absl import app, flags, logging
from absl.flags import FLAGS
def send_unity_data(arg):
context = zmq.Context()
socket = context.socket(zmq.ROUTER)
socket.bind("tcp://*:8080")
while True:
if(arg.poll()):
message=arg.recv()
x = { "x":str(message[0]), "y":str(message[1])}
app_json = json.dumps(x)
socket.send_string(app_json)
message = socket.recv()
print("Received request: %s" % message)
def streaming(detection,args):
try:
vid = cv2.VideoCapture(int(FLAGS.video))
except:
vid = cv2.VideoCapture(FLAGS.video)
receiver1 , sender1 = mp.Pipe()
b_proc3 = Process(target=send_unity_data, args=[receiver1])
b_proc3.start()
while(True):
...
def Main(_argv):
receiver , sender = mp.Pipe()
b_proc = Process(target=streaming, args=[receiver,FLAGS])
b_proc.start()
while(True):
...
I want to send positional coordinates to an Unity application, which is calculated by the streaming process, if someone has a better way to do it, I can change my code as well. 我想将位置坐标发送到由流处理计算的Unity应用程序,如果有人有更好的方法,我也可以更改代码。
Without deeper analysis, your code uses blocking-mode operations, which will block, whenever there are no messages yet in the Context()
-s instance receiving queue and the code submits a call to a socket.recv()
-method, like in the message = socket.recv()
SLOC above. 如果不进行更深入的分析,您的代码将使用阻塞模式操作,只要Context()
s实例接收队列中还没有消息,并且代码将调用提交给socket.recv()
- socket.recv()
该操作。 message = socket.recv()
上面的message = socket.recv()
SLOC。
Designing multi-layer / multi-process coordination is to avoid each and every potential blocking - ZeroMQ has .poll()
-methods for non-blocking or deterministic ( max-latency-budget consolidated MUX-ed ) priority polling (mainloop-alike)-"Controller"-policies. 设计多层/多进程协调是为了避免每个潜在的阻塞.poll()
具有.poll()
-非阻塞或确定性(最大延迟预算合并的MUX版本)优先级轮询(类似mainloop)的方法-“控制者”政策。
Feel free to read more details about how to best use ZeroMQ Hierarchy for your projects. 随时阅读有关如何在项目中最佳使用ZeroMQ层次结构的更多详细信息。
multiprocessing
module has other defaults and exhibits other behaviour than the tools based on the ZeroMQ messaging/signaling infrastructure. 除了基于ZeroMQ消息传递/信令基础结构的工具外, multiprocessing
模块还具有其他默认值,并且表现出其他行为。 Best use the ZeroMQ on both sides - no need to rely on 2nd layer of multiprocessing.Pipe
tools for delivering content into ZeroMQ operating realms. 最好在两侧都使用ZeroMQ-无需依赖第二层multiprocessing.Pipe
。管道工具可将内容传送到ZeroMQ操作领域。 ZeroMQ stack-less transport classes, as inproc://
and ipc://
and even cluster-wide tipc://
deliver way better performance as they may ejnoy a Zero-Copy for ultimate shaving off the processing latency. 诸如inproc://
和ipc://
甚至整个集群范围内的tipc://
ZeroMQ无栈传输类都提供了更好的性能,因为它们可能会拒绝零拷贝以最终减少处理延迟。
Anyway, avoid all blocking forms of methods being called and design a code so that it does not depend on (not yet, the more on not ever) delivered messages: 无论如何,请避免调用所有阻塞形式的方法,并设计代码,以使其不依赖于(但绝不依赖于)传递的消息:
def send_unity_data( arg ): ### an ad-hoc called
context = zmq.Context() ### 1st: spends time to instantiate a .Context()
socket = context.socket( zmq.ROUTER ) ### 2nd: spends time to instantiate a .socket()
socket.bind("tcp://*:8080") ### 3rd: spends time to ask/acquire O/S port(s)
while True: ### INFINITE-LOOP----------------------------------------
if( arg.poll() ### ?-?-?-?-?-?-? MAY BLOCK depending on arg's .poll()-method
): ### IF .poll()-ed:
message = arg.recv() ### ?-?-?-?-?-?-? MAY BLOCK till a call to arg.recv()-finished
x = { "x": str( message[0] ), ### try to assemble a dict{}
"y": str( message[1] ) ### based on both message structure
} ### and content
app_json = json.dumps( x ) ### try to JSON-ify the dict{}
socket.send_string( app_json ) ### x-x-x-x-x-x-x WILL BLOCK till a socket.send_string() finished
message = socket.recv() ### x-x-x-x-x-x-x WILL BLOCK till a socket.recv()is ever finished
print( "Received request: %s" ### try to print
% message ### a representation of a <message>
) ### on CLI
########################################### This is
# SPIN/LOOP OTHEWRISE ### hasty to O/S resources, wasting GIL-lock latency masking
########################################################################################################
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.