如何只创建分配了名称的线程,使得同名线程不活动? 例如:
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/