python - 当 threading.active_count() 返回 1 时,我可以假设我的线程已完成吗?

标签 python multithreading python-multithreading

给定以下类:

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 时完成。 - 也是我在 run 方法中使用的循环条件。

最佳答案

你可以假设你的线程在 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()

关于python - 当 threading.active_count() 返回 1 时,我可以假设我的线程已完成吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40766900/

相关文章:

python - 一个大正则表达式是否比一堆小正则表达式更有效?

python - 在 Django StaticLiveServerTestCase 期间在测试输出中显示服务器错误?

Python类实例在新线程中启动方法

python - 使用生成器在 python 中线程化

python - 如何在不浪费太多 cpu 周期的情况下等到多线程队列不为空

python - Numpy:为什么 'a += a.T' 不起作用?

python - 动态过滤来自 sqlalchemy 的数据

c# - Thread.Interrupt 等效于任务 TPL

java.lang.NoClassDefFoundError 仅在特定条件下

multithreading - 如何在不使用join的情况下向python中的主线程发送信号?