Я относительно новичок в 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()
То, что я не понимаю, что когда я вызываю функцию «стоп», программа иногда выходит из строя, так как выбор свободен, потому что EOF записывается в буфере стандартного вывода, но isStopping по-прежнему ложно. Как это может произойти?
Проблема с помещением terminate в run() заключается в том, что программа не будет завершена немедленно по запросу, поскольку она может зависеть от вызова select.select. Поэтому в этом случае я мог бы застрять в ожидании до 1 минуты, чтобы программа закончилась. – goloap
Затем вы можете использовать параметр тайм-аута в выборе или отправить сигнал ('import os, signal; os.kill (0, signal.SIGPIPE)') перед 'self.join()'. Документация по выбору показывает, что если сигнал получен, select() будет тайм-аут при приеме сигнала – tito
Звучит неплохо, но это не работает. Я изменил свой код следующим образом: 'ready, _, _ = select.select ([p.stdout], [], []); if (self.isStopping или (не готов)): continue' и в функции stop (self) у меня есть self.isStopping = True; os.kill (0, signal.SIGPIPE); self.join() ' Сигнал достигает выбора, но переменная' ready' всегда является файловым дескриптором: _ [', mode 'rb' at 0xb2ce40>] _, поэтому я сталкиваюсь с той же проблемой , Поскольку сигнал делает тайм-аут выбора, не должен ли 'ready' быть пустым списком? Я делаю что-то неправильно? –
goloap