我可以假设我的线程是在螺纹时完成的.active_count()返回1



给定以下类:

from abc import ABCMeta, abstractmethod
from time import sleep
import threading
from threading import active_count, Thread
class ScraperPool(metaclass=ABCMeta):
    Queue = []
    ResultList = []
    def __init__(self, Queue, MaxNumWorkers=0, ItemsPerWorker=50):
        # Initialize attributes
        self.MaxNumWorkers = MaxNumWorkers
        self.ItemsPerWorker = ItemsPerWorker
        self.Queue = Queue # For testing purposes.
    def initWorkerPool(self, PrintIDs=True):
        for w in range(self.NumWorkers()):
            Thread(target=self.worker, args=(w + 1, PrintIDs,)).start()
            sleep(1) # Explicitly wait one second for this worker to start.
    def run(self):
        self.initWorkerPool()
        # Wait until all workers (i.e. threads) are done.
        while active_count() > 1:
            print("Active threads: " + str(active_count()))
            sleep(5)
        self.HandleResults()
    def worker(self, id, printID):
        if printID:
            print("Starting worker " + str(id) + ".")
        while (len(self.Queue) > 0):
            self.scraperMethod()
        if printID:
            print("Worker " + str(id) + " is quiting.")
        # Todo Kill is this Thread.
        return
    def NumWorkers(self):
        return 1 # Simplified for testing purposes.
    @abstractmethod
    def scraperMethod(self): 
        pass
class TestScraper(ScraperPool):
    def scraperMethod(self):
        # print("I am scraping.")
        # print("Scraping. Threads#: " + str(active_count()))
        temp_item = self.Queue[-1]
        self.Queue.pop()
        self.ResultList.append(temp_item)
    def HandleResults(self):
        print(self.ResultList)
ScraperPool.register(TestScraper)
scraper = TestScraper(Queue=["Jaap", "Piet"])
scraper.run()
print(threading.active_count())
# print(scraper.ResultList)

完成所有线程完成后,仍然有一个活动线程-threading.active_count()在最后一行中得到我的数字。

活动线程为<_MainThread(MainThread, started 12960)>-用threading.enumerate()打印。

我可以假设我所有的线程都在active_count() == 1时完成吗?或例如,可以导入的模块启动其他线程,以便在active_count() > 1时实际完成我的线程 - 也是我在运行方法中使用的环路的条件。

您可以假设您的线程是在active_count()达到1时完成的。问题是,如果任何其他模块创建线程,您将永远不会达到1。您应该明确管理线程。

示例:您可以将线程放入列表中,然后一次加入它们。代码的相关更改是:

def __init__(self, Queue, MaxNumWorkers=0, ItemsPerWorker=50):
    # Initialize attributes
    self.MaxNumWorkers = MaxNumWorkers
    self.ItemsPerWorker = ItemsPerWorker
    self.Queue = Queue # For testing purposes.
    self.WorkerThreads = []
def initWorkerPool(self, PrintIDs=True):
    for w in range(self.NumWorkers()):
        thread = Thread(target=self.worker, args=(w + 1, PrintIDs,))
        self.WorkerThreads.append(thread)
        thread.start()
        sleep(1) # Explicitly wait one second for this worker to start.
def run(self):
    self.initWorkerPool()
    # Wait until all workers (i.e. threads) are done. Waiting in order
    # so some threads further in the list may finish first, but we
    # will get to all of them eventually
    while self.WorkerThreads:
        self.WorkerThreads[0].join()
    self.HandleResults()

根据文档active_count()包括主线程,因此,如果您在1处,则很可能完成,但是如果您程序中有其他新线程来源,则可以在active_count()命中之前完成1.

我建议在您的ScraperPool上实现明确的join方法,并跟踪工人并在需要时明确将其加入到主线程中,而不是检查您对active_count()调用的完成。

还记得有关吉尔...

最新更新