我是python的新手,但不是多线程软件,所以我无法解释我所看到的特定行为。我的程序非常简单:我监视linux命令'iostat'的输出并在某些情况下执行某些操作。我的代码如下:
class SysMonitor(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.isStopping = False
self.ioprocess = []
def run(self):
self.ioprocess = subprocess.Popen(['/usr/bin/iostat', '-p', 'sda', '60'], stdout=subprocess.PIPE)
p = self.ioprocess
i = 0
# Discard first output
while (i < 11):
p.stdout.readline()
i = i + 1
# Now keep on waiting on new output from iostat and then process it when it comes in
while (not self.isStopping):
select.select([p.stdout], [], [])
# Don't process the last output if we are stopping
if (self.isStopping):
print 'Quitting, discarding last buffer:' + str(self.isStopping)
continue
# do some p.stdout.readline() and process the data
def stop(self):
self.isStopping = True
self.ioprocess.terminate()
我不明白的是,当我调用'stop'函数时,程序有时会崩溃因为select被释放,因为EOF是在stdout缓冲区中写的,但isStopping仍然是False。怎么会发生这种情况?
答案 0 :(得分:2)
如果在线程外调用stop()
,则可能导致随机问题。因为当你调用stop()时,线程无论如何都可以是打印,还是选择等等。
只需在terminate()
方法的末尾移动run()
即可。然后将isStopping
设置为True将正确地离开循环,然后终止该过程。
如果您想等待它,可以加入以下内容:
def stop(self):
self.isStopping = True
self.join()
答案 1 :(得分:2)
以tito's answer为基础,关于您的评论,您可以在select.select
中使用超时:
while (not self.isStopping):
ready, _, _ = select.select([p.stdout], [], [], 5.0)
# Don't process the last output if we are stopping
if (self.isStopping):
print 'Quitting, discarding last buffer:' + str(self.isStopping)
continue
if ready:
# do some p.stdout.readline() and process the data
self.ioprocess.terminate()
以上,超时为5.0秒。我认为这足够长,不会锤击系统,并且足够短以便合理终止。改变以适合您的口味。
答案 2 :(得分:0)
如果目标是在应用程序结束时结束线程,则将线程设置为守护进程。