如果 stdout/stderr 中没有活动,如何终止子进程

如果 stdout/stderr 中没有活动,如何终止子进程

问题描述:

我正在从 python 脚本运行程序(当前使用 os.system).但是,有时程序会在某个点挂起,如果在某个时间间隔后没有向 stdout 或 stderr 写入任何内容,我想终止它.程序上的简单超时将不起作用,因为此代码通常运行很长时间(数小时到数天),有时它在还有很长的路要走之前挂起.

I am running a program from a python script (currently with os.system). However, sometimes the program hangs at a point and I would like to kill it if nothing is written to stdout or stderr after a certain time interval. A simple timeout on the program won't work, because this code typically runs for a very long time (many hours to days), and sometimes it hangs before it still has a long way to go.

似乎 subprocess.Popen 是要走的路,但我还没有找到一个很好的例子来说明如何做到这一点.我还想将 stdout/stderr 写入文件.

It seems that subprocess.Popen is the way to go, but I haven't found a good example on how to do this. I also wanted to write the stdout/stderr to a file.

基于一些例子,我在考虑这样的事情:

Based on some examples I was thinking about something like this:

p = Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None)

while True:
    line = p.stdout.readline()
    outfile.write(line)
    # save current time or something, compare to time of
    # previous loop, if larger than timeout, kill process

但我不确定如何实现时间循环,以及如何确保 while 在进程最终自行终止时不会永远运行(并且不会挂起)).任何指针将不胜感激.

But I'm not sure how to implement the time loop, and how to make sure that the while doesn't run forever when the process eventually terminates on its own (and doesn't hang). Any pointers would be much appreciated.

尝试使用signal.alarm在每行接收到后设置一个定时器,然后处理SIGALRM通过检查自上一行以来是否过去了太多时间.

Try using signal.alarm to set a timer after each line is received, and then handle SIGALRM by checking if too much time has passed since the last line.