简体   繁体   English

Python子进程被子进程卡住

[英]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应用程序,如果有人有更好的方法,我也可以更改代码。

Avoid any undeterministically long blocking state in Video streaming 避免视频流中任何不确定的长时间阻塞状态

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层次结构的更多详细信息。


Where the code blocks? 代码在哪里? Let's review the as-is state: 让我们回顾一下现状:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM