我有一個簡單的項目,我需要並行打印進度信息,例如進度條。並行打印和寫入鎖
每個小節都有一個位置,終端中的書寫指針會根據小節的位置上下移動。
這在串行完成時效果很好,但由於賽車問題而平行打印時失敗。我試圖使用multiprocessing.Lock()
,但無濟於事。
這裏是我當前的代碼:
from __future__ import division
import os, sys
import signal
from time import sleep
from multiprocessing import Pool, freeze_support, Lock
if os.name == 'nt':
import colorama # to support cursor up
colorama.init()
_term_move_up = '\x1b[A'
write_lock = Lock()
class simple_bar(object):
def __init__(self, iterable, desc='', position=0):
signal.signal(signal.SIGINT, signal.SIG_IGN) # handles keyboardinterrupt
self.iterable = iterable
self.total = len(iterable)
self.n = 0
self.position = position
self.desc = desc
self.display()
def __iter__(self):
for obj in self.iterable:
yield obj
self.update()
def update(self, n=1):
self.n += n
self.display()
def display(self, fp=None, width=79):
if not fp:
fp = sys.stdout
with write_lock:
fp.write('\n' * self.position)
l_part = self.desc + ': '
bar = l_part + '#' * int((self.n/self.total) * (width - len(l_part)))
fp.write('\r' + bar + ' ' * (width - len(bar)))
fp.write(_term_move_up * self.position)
fp.flush()
def progresser(n):
text = "progresser #{}".format(n)
for i in simple_bar(range(5000), desc=text, position=n):
sleep(0.001)
if __name__ == '__main__':
freeze_support()
L = list(range(3))
Pool(len(L)).map(progresser, L)
該工程確定序列替代,這給正確的輸出應該由上面的水貨版本製作:
# Same code as above, except __main__
if __name__ == '__main__':
t_list = [simple_bar(range(5000), desc="progresser #{}".format(n), position=n) for n in xrange(3)]
for i in range(5000):
for t in t_list:
t.update()
我不知道是什麼出錯了。我在Windows 7
我正在尋找一種方法來並行打印安全的多處理和理想,但可選線程安全使用Python 2.7.12。
/編輯:有趣的是,如果我把一個等待(但也足夠大)打印前,那麼條好嗎印刷:
# ...
def display(self, fp=None, width=79):
if not fp:
fp = sys.stdout
with write_lock:
sleep(1) # this fixes the issue by adding a delay
fp.write('\n' * self.position)
l_part = self.desc + ': '
bar = l_part + '#' * int((self.n/self.total) * (width - len(l_part)))
fp.write('\r' + bar + ' ' * (width - len(bar)))
fp.write(_term_move_up * self.position)
fp.flush()
# ...
我不知道這意味着什麼結論。
不知道我理解正確。你想同時處理一些工作並在完成一部分工作時打印進度條嗎?進度是否由您的子流程或您的主流程打印是否重要? – noxdafox
@noxdafox對於第一個問題,對於第二個問題,是應該從子進程打印進度,這是問題所在。從主流程來看,沒有問題,因爲沒有涉及到併發。 – gaborous