我怎么知道子进程正在等待GUI上的输入

时间:2017-05-26 05:42:15

标签: python multithreading tkinter subprocess

我正在编写一个顶级脚本(python)来控制IC设计流程上的EDA工具,顶级脚本有一个GUI(python-tkinter),用subprocess.Popen()运行EDA工具,打印stdout GUI。

有时EDA工具不会退出但是等待输入,然后GUI将挂起并等待我的输入,但是top-script无法从subprocess.stdout捕获正确的stdout消息,并且无法将我的输入放入子进程。

以下是我的顶级脚本的一部分。

class runBlocks():
    ... ...
    def subprocessRun(self):
        # run EDA tool "runCommand" with subprocess.Popen.
        self.RC = subprocess.Popen(runCommand, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

        # save subprocess stdout into queue.
        self.queue = queue.Queue()
        getRunProcessThread = threading.Thread(target=self.getRunProcess)
        getRunProcessThread.setDaemon(True)
        getRunProcessThread.start()

        # update GUI with the stdout (on queue).
        self.updateRunProcess()

        # wait for subprocess finish.
        (stdout, stderr) = self.RC.communicate()
        return(self.RC.returncode)

    def getRunProcess(self):
        # no block getting subprocess.stdout
        while self.RC.poll() == None:
            stdoutLine = str(self.RC.stdout.readline(), encoding='utf-8')
            self.queue.put(stdoutLine)

    def updateRunProcess(self):
        # if there is still something from subprocess.stdout, print them into GUI Text.
        while self.RC.poll() == None or not self.queue.empty():
            if self.queue.empty():
                time.sleep(0.1)
                conitnue
            else:
                line = self.queue.get_nowait()
                if line:
                    # "self.runProcessText" is a Text on GUI, accept EDA tool output message.
                    self.runProcessText.insert(END, line)
                    # "self.runProcessText" is on "self.frame6", after inserting new message, update the frame.
                    self.frame6.update()
                    self.runProcessText.see(END)

如果我直接在终端上运行EDA工具,它将停止并等待我的输入。

$ dc_shell-t -64 -topo -f ./analyze.run.tcl -o analyze.log
...
$ #quit
$ dc_shell-topo>

如果我使用我的顶级脚本运行EDA工具,则subprocess.stdout将在消息“#quit”上停止,我无法获得消息“dc_shell-topo>”。

...
#quit

我知道子进程正在等待我的输入,但GUI将在消息“#quit”上停止,并在while命令上挂起“time.sleep(0.1)”。

我也尝试用“self.GUItop.after(100,self.updateRunProcess)”替换“time.sleep(0.1)”,然后stdout将通过“dc_shell-topo>”命令没有任何输入,然后直接完成。

...
dc_shell=topo>
Memory usage for main task 82 Mbytes.
CPU usage for this session 6 seconds ...
Thank you...

我的预期行为是:

  1. 当命令以“dc_shell-topo>”停止时在子进程上,我可以使用subprocess.stdout获取消息。

  2. 等待输入时,GUI不会挂起。

  3. 我的问题是:

    1. 为什么使用“time.sleep()”和“self.GUItop.after()”会影响subprocess.stdout消息?

    2. 当EDA工具正在等待输入消息“dc_shell-topo>”时在子进程上,我怎样才能在subprocess.stdout()上获得这样的消息?

    3. 当使用self.GUItop.after时,在子进程完成之前的GUI Text(它正在等待cpu free),但没有self.GUItop.after,GUI将挂起time.sleep()命令,如何解决这个问题?

    4. 我认为这确实是一个令人头疼的问题,我已经在谷歌上阅读了数千个相关问题,但没有一个能回答我的问题。

0 个答案:

没有答案