2

我正在尝试创建一个网络提取器,我有这个多线程代码,我需要打印扫描仪的状态/进度:

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)但它不起作用?

4

1 回答 1

2

Queue对象没有,len因为就其本质而言,它们是跨线程共享的,这将是不准确和误导的。

但是,他们有一种qsize方法可以为您提供近似大小,正是出于这种目的。


如果您想要精确的值,则需要一秒钟Queue,其中每个任务都将某些内容放在队列中,并且一些额外的线程(或可能是主线程)循环它并计算到目前为止完成的任务。或者,或者,更简单的东西,例如具有全局保护它的全局int计数器。Lock


但是,我认为用池或执行器来编写它会简单得多。这将为您处理排队任务,并将每个任务的值返回到主线程,而您无需管理任何内容。例如,使用2.xfutures的 Python 3.xconcurrent.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!"
于 2013-09-09T20:14:39.900 回答