簡體   English   中英

Python子進程被子進程卡住

[英]Python subprocess gets stuck by a child process

我試圖在子流程中調用一個子流程,以便使用ZMQ將信息發送到Unity應用程序。 當我打電話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):
    ...

我想將位置坐標發送到由流處理計算的Unity應用程序,如果有人有更好的方法,我也可以更改代碼。

避免視頻流中任何不確定的長時間阻塞狀態

如果不進行更深入的分析,您的代碼將使用阻塞模式操作,只要Context() s實例接收隊列中還沒有消息,並且代碼將調用提交給socket.recv() - socket.recv()該操作。 message = socket.recv()上面的message = socket.recv() SLOC。

設計多層/多進程協調是為了避免每個潛在的阻塞.poll()具有.poll() -非阻塞或確定性(最大延遲預算合並的MUX版本)優先級輪詢(類似mainloop)的方法-“控制者”政策。

隨時閱讀有關如何在項目中最佳使用ZeroMQ層次結構的更多詳細信息。


代碼在哪里? 讓我們回顧一下現狀:

除了基於ZeroMQ消息傳遞/信令基礎結構的工具外, multiprocessing模塊還具有其他默認值,並且表現出其他行為。 最好在兩側都使用ZeroMQ-無需依賴第二層multiprocessing.Pipe 。管道工具可將內容傳送到ZeroMQ操作領域。 諸如inproc://ipc://甚至整個集群范圍內的tipc:// ZeroMQ無棧傳輸類都提供了更好的性能,因為它們可能會拒絕零拷貝以最終減少處理延遲。

無論如何,請避免調用所有阻塞形式的方法,並設計代碼,以使其不依賴於(但絕不依賴於)傳遞的消息:

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