尝试在Python 3.11中的while循环内并发运行线程

huangapple go评论51阅读模式
英文:

Attempting to run threads concurrently inside while loop in Python 3.11

问题

我正在努力理解Python 3.11中的线程处理,并试图弄清楚为什么当我在execute_subtasks中加入time.sleep(120)时,下一个线程没有被处理,代码似乎是顺序运行而不是并发运行。

我需要在for循环外面启动线程,还是需要移动join的位置?

英文:

I am trying to get my head around threading in Python 3.11 and I am trying to work out why when I put a time.sleep(120) inside execute_subtasks that the next thread is not processed and the code appears to run sequentially instead of concurrently.

Do I need to start the thread outside of the for loop or do I need to move the location of the join?

from threading import Thread, Event, active_count, current_thread

threads = list()
while True:
    try:
        # ignore the main thread
        if active_count() > 1:
            for index, thread in enumerate(threads):
                thread.join()

        for message in queue.get_messages(4):
            if active_count() >= config.maxthreads + 1:
                # Thread pool is about to overflow. Skipping.
                continue

            x = threading.Thread(
                target=message.get_task().execute_subtasks,
                daemon=True,
                args=[message.get_context()]
            )
            threads.append(x)
            x.start()
    except Exception:
        # Exception in dispatch loop

答案1

得分: 1

不需要在加入已停止的线程时使用 active_count(),因为你唯一关心的线程都在你的 threads 列表中。

实现这个函数...

def remove_dead_threads(_list):
    for thread in [t for t in _list if not t.is_alive()]:
        thread.join()
        _list.remove(thread)

然后,在 try: 后的第一行代码中执行...

remove_dead_threads(threads)

这将通过加入那些不再存活的线程来清理你的 threads 列表。

你还可以考虑使用 ThreadPoolExecutor 来简化线程池管理。

英文:

You do not need to use active_count() when joining dead threads because the only threads you're interested in are in your threads list.

Implement this function...

def remove_dead_threads(_list):
    for thread in [t for t in _list if not t.is_alive()]:
        thread.join()
        _list.remove(thread)

Then, as the first line of code after try: do...

remove_dead_threads(threads)

This will clean up your threads list by joining those that are no longer alive.

You could also consider using a ThreadPoolExecutor to make pool management easier

huangapple
  • 本文由 发表于 2023年2月24日 17:22:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/75554738.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定