我正在尝试创建一个Web提取器,我有多线程的代码,我需要打印扫描仪的状态/进度:
import time
import threading
import Queue
import sys
try:
Lista = open(sys.argv[1], "r").readlines()
except(IOError):
print "Error: Check your ip list path\n"
sys.exit(1)
class WorkerThread(threading.Thread) :
def __init__(self, queue) :
threading.Thread.__init__(self)
self.queue = queue
def run(self) :
while True :
counter = self.queue.get()
sys.stdout.write("line nr : \r")
self.queue.task_done()
queue = Queue.Queue()
for i in range(50) :
worker = WorkerThread(queue)
worker.setDaemon(True)
worker.start()
for line in Lista:
queue.put(line)
queue.join()
print "All task over!"
如何在扫描仪工作时打印状态/进度,我试过len(queue)
但它不起作用?
答案 0 :(得分:2)
Queue
个对象没有len
,因为就其本质而言,它们是在线程之间共享的,并且会导致不准确和误导。
但是,他们使用qsize
方法为您提供大致的尺寸,正是出于这种目的。
如果你想要完全值,那么你需要第二个Queue
,其中每个任务都将一些东西放在出队列上,还有一些额外的线程(或者可能是主线程)循环遍历它并计算到目前为止完成的任务。或者,或者更简单的事情,例如全局int
计数器,全局Lock
保护它。
但是,我认为用池或执行器来编写它会简单得多。这将负责为您排队任务,并将每个值返回到主线程,而无需管理任何内容。例如,使用futures
,2.x的Python 3.x concurrent.futures
模块的后端,这是您的整个程序,添加了进度:
import sys
import futures
try:
Lista = open(sys.argv[1], "r").readlines()
except(IOError):
print "Error: Check your ip list path\n"
sys.exit(1)
def task(line):
# Do something
with futures.ThreadPoolExecutor(50) as executor:
fs = [executor.submit(task, line) for line in Lista]
for i, f in enumerate(futures.as_completed(fs)):
sys.stdout.write("line nr: {} / {} \r".format(i, len(Lista)))
print "All task over!"