我有下面的python3程序,它創建一些工作進程並在我點擊ctrl-c時殺死它們。 在將SIGTERM發送到子進程之前,主控制檯在控制檯print('[W] aghhh ... %d' % self.pid)
上打印一行。問題在於,對於給定的進程,該行會輸出多次。像這樣(實際控制檯輸出):Python:在進程打印後多次打印到控制檯
[W] aghhh ... 15773
[W] aghhh ... 15773
[W] aghhh ... 15774
[W] aghhh ... 15773
[W] aghhh ... 15774
[W] aghhh ... 15775
[W] aghhh ... 15776
問題:這怎麼可能? 什麼是殺死兒童過程的正確方法?
代碼:
import os
import time
import signal
import sys
class ChildProcess:
def __init__(self, m):
self.pid = None
self.ttl = 10
self.master = m
self.pipe_in = None
self.pipe_out = None
def hey(self):
self.ttl -= 1
self.pipe_out.write('Hello worker %d\n' % self.pid)
self.pipe_out.flush()
def tell_me(self):
msg = self.pipe_in.readline()
print('[M] Worker process %d says: %s' % (self.pid, msg), end='')
def live(self):
r1, w1 = os.pipe()
r2, w2 = os.pipe()
pid = os.fork()
self.pid = pid
if pid:
print('[M] Created worker process %d' % pid)
os.close(w1)
os.close(r2)
self.pipe_in = os.fdopen(r1, 'rt')
self.pipe_out = os.fdopen(w2, 'wt')
self.master.add(self)
else:
print('[W] Worker process ready to rock')
os.close(r1)
os.close(w2)
wr = os.fdopen(w1, 'wt')
reader = os.fdopen(r2)
while True:
wr.write('Hello Master\n')
wr.flush()
msg = reader.readline()
print('[W] Master says %s' % msg, end='')
def die(self):
print('[W] aghhh ... %d' % self.pid)
os.kill(self.pid, signal.SIGTERM)
class Master:
def __init__(self):
self.workers = []
def add(self, worker):
self.workers.append(worker)
def rulez(self, nbr=2):
for i in range(nbr):
worker = ChildProcess(self)
worker.live()
while True:
for w in self.workers:
w.tell_me()
time.sleep(1)
w.hey()
def reap(self):
for w in self.workers:
w.die()
if __name__ == '__main__':
master = Master()
try:
master.rulez(3)
except KeyboardInterrupt:
master.reap()
您可能需要使用標誌的工作線程while循環,然後設置標誌設置爲false,當你想殺死工人。我的兩分錢.. – Jodgod
與你的印刷問題無關:你可以創建一個新的會話(在分岔孩子之前分叉主和呼叫setsid),然後你可以通過向流程組發送一個單一的信號來殺死他們:'os.killpg( master_pid,SIGKILL)' – jfs
您是否嘗試過使用未緩衝的標準流運行腳本 - '-u'標誌(或者在fork之前手動調用'sys.stdout.flush()''')? – jfs