[英]Inconsistent behavior when attempting to terminate python subprocess running on a thread
当我尝试终止在单独线程上运行的长时间运行的进程时,我遇到了问题。
下面是程序。 WorkOne创建一个子进程并运行一个长时间运行的进程“ adb logcat”,该进程会生成日志行。 我在main()中启动WorkOne,等待5秒钟,然后尝试将其停止。 多次运行可提供多个输出
import threading
import time
import subprocess
import sys
class WorkOne(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.event = threading.Event()
self.process = subprocess.Popen(['adb','logcat'], stdout=subprocess.PIPE, stderr=sys.stdout.fileno())
def run(self):
for line in iter(self.process.stdout.readline,''):
#print line
if self.event.is_set():
self.process.terminate()
self.process.kill()
break;
print 'exited For'
def stop(self):
self.event.set()
def main():
print 'starting worker1'
worker1 = WorkOne()
worker1.start()
print 'number of threads: ' + str(threading.active_count())
time.sleep(5)
worker1.stop()
worker1.join(5)
print 'number of threads: ' + str(threading.active_count())
if __name__ == '__main__':
main()
有时我得到[A]:
starting worker1
number of threads: 2
number of threads: 2
exited For
有时我得到[B]:
starting worker1
number of threads: 2
number of threads: 1
exited For
有时我得到[C]:
starting worker1
number of threads: 2
number of threads: 2
我想我应该一直得到[B]。 这是怎么了?
更改
if self.event.is_set():
self.process.terminate()
self.process.kill()
break;
至
if self.event.is_set():
self.process.terminate()
self.process.wait()
break
分号是一个死胡同,这里有一个问题。
我猜想,没有wait()
的线程有时会work1.join(5)
解除对work1.join(5)
的work1.join(5)
。 在这些情况下, threading.active_count()
返回2。
而且,正如@ A.Rodas所说, work1.join(5)
应该是work1.join()
以确保在work1
完成之前,连接不会解除阻塞。
顺便说一句,我不确定您为什么要调用terminate
然后连续kill
。 在Unix上,kill是更严重的终止形式。 在Windows上,它们是相同的。 因此,如果要呼叫kill,则无需呼叫终止。
由于您知道subprocess
调用的程序,因此您也应该知道终止是否足以停止它。
因此,您只需要一个: self.process.terminate()
或self.process.kill()
。
我认为[B]仅在子进程少于10秒的情况下才可能:主线程休眠5秒,然后该worker
线程在join()
的5秒超时内完成操作。
在10秒钟或更长时间内, worker
即使在join()
调用之后仍可以存活,因为它具有超时参数,这可能会发生也可能不会发生。 然后,您可以获得[A](子过程在几秒钟后完成)或[C](子过程在很晚之后完成)。
要始终获取[B],请删除join()
的超时参数,以便主线程等待直到worker
完成为止(或通过将kill调用置于循环外部来确保在10秒内终止该进程)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.