Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/232.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中,如何让线程同时等待管道输入和事件?_Python_Multithreading_Popen_Python Multithreading - Fatal编程技术网

在Python中,如何让线程同时等待管道输入和事件?

在Python中,如何让线程同时等待管道输入和事件?,python,multithreading,popen,python-multithreading,Python,Multithreading,Popen,Python Multithreading,在我正在开发的应用程序中,我有一个线程,当初始化时,通过将stdout重定向到PIPE来启动超级进程。在run()中,我需要在管道和事件上等待。 管道的输出必须在textview上输出。 设置事件后,线程必须停止从运行()返回 我的解决办法是 通过超时的select在管道上等待。select 然后,如果选择返回,则管道可读 从管道中读取一个字节,因此我确信此读取无法阻止 将字节存储在字节数组中,直到收到换行符 将bytearray输出到textviev 测试事件 这是可行的,但每次读

在我正在开发的应用程序中,我有一个线程,当初始化时,通过将
stdout
重定向到
PIPE
来启动超级进程。在
run()
中,我需要在管道和事件上等待。
管道的输出必须在textview上输出。
设置事件后,线程必须停止从
运行()返回

我的解决办法是

  • 通过超时的select在管道上等待。select
  • 然后,如果选择返回,则管道可读
    • 从管道中读取一个字节,因此我确信此读取无法阻止
    • 将字节存储在字节数组中,直到收到换行符
      • 将bytearray输出到textviev
  • 测试事件
这是可行的,但每次读取1字节的效率非常低
我想知道是否存在更有效的解决方案

这是我的代码片段:

class ProcessEcho(threading.Thread):

    def __init__(self,environ,command_line,textbuffer,on_process_exited_cb):
        super(ProcessEcho,self).__init__()

        self.textbuffer = textbuffer
        self.on_process_exited_cb = on_process_exited_cb

        self.popen = subprocess.Popen(command_line,stdout = subprocess.PIPE, stderr = subprocess.STDOUT,bufsize=0,env=environ)

        self.exit_event = threading.Event()

        self.daemon = True
        self.start()

    def get_pid(self):
        return self.popen.pid

    def stop(self):
        self.exit_event.set()

    def update_textbuffer(self,string):
        self.textbuffer.insert(self.textbuffer.get_end_iter(),string)

    def run(self):
        buffer = bytearray()
        while True:
            rl,wl,xl = select.select([self.popen.stdout], [], [], 1)

            if len(rl):
                r = self.popen.stdout.read(1)
                if r=='':
                    self.popen.communicate()
                    GObject.idle_add(self.on_process_exited_cb)
                    return
                else:
                    buffer.append(r)

                    if r == "\n":
                        GObject.idle_add(self.update_textbuffer,str(buffer))
                        buffer = bytearray()
            if self.exit_event.is_set():
                self.popen.communicate()
                GObject.idle_add(self.on_process_exited_cb)
                return

要在不阻塞的情况下读取流,请使用Queue.get_nowait()

如何将队列连接到管道?对不起,我没有仔细阅读您的回答:我不想在非阻塞模式下读取管道,我想阻止管道输入被“管道上可用的数据”或“事件设置”唤醒。我想等待线程进入内核模式,否则如果我在非阻塞模式下读取管道,线程将持续处于用户模式并加载cpu。然后使用“选择”等待,直到有数据可用。