python - 仅当不存在相同线程名称作为事件线程时才创建线程(Python)

标签 python multithreading

如何只创建分配了名称的线程,使得同名线程不活动? 例如:

threading.Thread(name='t1', target=foo).start() 
threading.Thread(name='t1', target=foo).start()

此处,由于名为 t1 的线程已经在运行,因此应取消第二个 t1。这是为了避免冗余线程执行相同的任务。但是,一旦第一个 t1 死亡,并且另一个具有相同名称的线程即“t1”到达,那么它应该运行。
约束是:10 个以上的线程可能会尝试生成。线程名称是使用 random.randint(1,10) 生成的。所以,我只需要在运行时检查线程名称。

这是我的代码:

import logging
import time
import threading
import random

logging.basicConfig(level=logging.DEBUG, format='[%(levelname)s] (%(threadName)-10s) %(message)s', )

e = threading.Event()
Thread_list = ['default']

def worker():
    logging.info('Starting')
    time.sleep(3)
    logging.info('Ending')
    try:
        Thread_list.remove(threading.currentThread().getName())
    except:
        pass
    return

def application_manager(appId):
    #print threading.enumerate()
    event_is_set = e.wait(2)
    if event_is_set:
        th = threading.Thread(name=appId, target=worker)
        Thread_list.append(threading.currentThread().getName())
        th.start()
    else:
        logging.warning('Task already running.')

def subsystem_request():
    for i in range(10):
        appId = random.randint(1,10)
        application_manager(appId)

def fdir():
    logging.debug('FDIR')
    count = 0
    cur = threading.currentThread()
    time.sleep(2)
    for fd in range(5):
        e.clear()
        for t in threading.enumerate():
            for u in threading.enumerate():
                if t.getName() == cur:
                    e.set()
                elif (t.getName() in u.getName()) and (t.getName() != 'MainThread'):
                    e.clear()
                else:
                    e.set()


fdir_thread = threading.Thread(name='fdir_thread', target=fdir)
fdir_thread.setDaemon(True)
fdir_thread.start()
subsystem_request()

fdir_thread.join()

实际输出:

[DEBUG] (fdir_thread) FDIR
[WARNING] (MainThread) Task already running.
[WARNING] (MainThread) Task already running.
[WARNING] (MainThread) Task already running.
[WARNING] (MainThread) Task already running.
[WARNING] (MainThread) Task already running.
[WARNING] (MainThread) Task already running.
[WARNING] (MainThread) Task already running.
[WARNING] (MainThread) Task already running.
[WARNING] (MainThread) Task already running.
[WARNING] (MainThread) Task already running.

另一个实际输出:

[INFO] (9         ) Starting
[INFO] (7         ) Starting
[INFO] (1         ) Starting
[INFO] (9         ) Starting     //This thread should be cancelled  
[INFO] (4         ) Starting
[INFO] (10        ) Starting
[INFO] (2         ) Starting
[INFO] (7         ) Starting     //This thread should be cancelled  
[INFO] (5         ) Starting
[INFO] (8         ) Starting
[INFO] (9         ) Ending
[INFO] (1         ) Ending
[INFO] (7         ) Ending
[INFO] (9         ) Ending
[INFO] (2         ) Ending
[INFO] (10        ) Ending
[INFO] (4         ) Ending
[INFO] (7         ) Ending
[INFO] (5         ) Ending
[INFO] (8         ) Ending 

预期输出:

[INFO] (9         ) Starting
[INFO] (7         ) Starting
[INFO] (1         ) Starting
[INFO] (4         ) Starting
[INFO] (10        ) Starting
[INFO] (2         ) Starting
[INFO] (5         ) Starting
[INFO] (8         ) Starting
[INFO] (9         ) Ending
[INFO] (1         ) Ending
[INFO] (7         ) Ending
[INFO] (2         ) Ending
[INFO] (10        ) Ending
[INFO] (4         ) Ending
[INFO] (5         ) Ending
[INFO] (8         ) Ending

这些事件线程中的每一个都有唯一的名称。
我正在使用 threading.Event()。因此,函数 application_manager 等待 2 秒,然后 func fdir() 使用 threading.enumerate() 检查相同的名称,如果是,则使用 e.clear(),否则使用 e.set()。一旦,e.set(),application_manager() 将创建线程。

我想使用 fdir() 检查然后与 application_manager() 通信以生成或取消线程。
注意:fdir() 和 application_manager() 应该是 2 个不同的线程。

最佳答案

更好的方法是重构您的代码以使用 Lock对象

t1 = threading.Lock()

def foo(*args):
    if not t1.acquire(wait=False):
         return

    # do stuff

虽然这完全符合您的描述 - 即如果其他东西持有锁,则执行将被“取消”,您最好进行重构以避免完全调用线程。

关于python - 仅当不存在相同线程名称作为事件线程时才创建线程(Python),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33284933/

相关文章:

java - 多线程中的实例变量行为

python - 有没有办法遍历给函数的每个变量并确定其类型?

python - Mac + Anaconda 上的 Qt 设计器应用程序在哪里?

python - 使用 pcapy/impacket 更改数据包数据

python - 如何使用 Django Streaming HTTPS Response 正确渲染图像?

Python - 我应该使用线程还是进程来进行网络事件?

python - 移动 Numpy 数组的最快方法

mysql - 无法连接到 'localhost' (111) 上的 MySQL 服务器

java - 如何分析 Java 中的线程转储以最大限度地减少高 CPU 使用率

具有共享变量的 Python 多处理/线程只能读取