我最近面臨着將多進程操作納入我們的軟件的挑戰。我想要一個主進程產生子進程,並且我需要一些將日誌信息發送回主進程的方式。這主要是因爲我們使用的模塊將警告和錯誤消息寫入日誌記錄對象,我們希望這些消息出現在主進程中運行的gui中。Python 3:使用多處理隊列進行日誌記錄
明顯的方法是用write()方法編寫一個小類,將write()放入隊列中,然後在日誌流處理程序中使用此類。然後主進程從這個隊列中獲取()將文本發送給gui。但這似乎沒有工作,我不知道爲什麼
我寫了一些示例代碼來演示問題。它使用日誌記錄對象在子進程中寫入隊列,然後主進程嘗試從隊列中讀取,但失敗。有人能幫我弄清楚這有什麼問題嗎?
import time, multiprocessing, queue, logging
class FileLikeQueue:
"""A file-like object that writes to a queue"""
def __init__(self, q):
self.q = q
def write(self, t):
self.q.put(t)
def flush(self):
pass
def func(q):
"""This function just writes the time every second for five
seconds and then returns. The time is sent to the queue and
to a logging object"""
stream = FileLikeQueue(q)
log = logging.getLogger()
infohandler = logging.StreamHandler(stream)
infohandler.setLevel(logging.INFO)
infoformatter = logging.Formatter("%(message)s")
infohandler.setFormatter(infoformatter)
log.addHandler(infohandler)
t1 = time.time()
while time.time() - t1 < 5: #run for five seconds
log.info('Logging: ' + str(time.time()))
q.put('Put: %s' % str(time.time()))
time.sleep(1)
def main():
q = multiprocessing.Queue()
p = multiprocessing.Process(target=func, args=(q,))
p.start()
#read the queue until it is empty
while True:
try:
t = q.get()
except queue.Empty:
break
print(t)
if __name__ == '__main__':
main()
我期望的輸出是:
Logging: 1333629221.01
Put: 1333629221.01
Logging: 1333629222.02
Put: 1333629222.02
Logging: 1333629223.02
Put: 1333629223.02
Logging: 1333629224.02
Put: 1333629224.02
Logging: 1333629225.02
Put: 1333629225.02
但我得到的是:
Put: 1333629221.01
Put: 1333629222.02
Put: 1333629223.02
Put: 1333629224.02
Put: 1333629225.02
所以認沽()在FUNC操作()的作品,但記錄沒有按「T。爲什麼?
謝謝。
我沒有深入你的代碼,但如果你正在嘗試登錄多路處理環境,你可能會發現[這個答案](http://stackoverflow.com/a/9823098/1132524),我寫的不是很久以前,很有用。 – 2012-04-05 13:16:50
感謝這個Rik,這也有幫助。 – 2012-04-05 13:23:15