我创建了一个deco来用相同的方法在多线程中运行一堆东西
import threading
from functools import wraps
class ThreadingMask:
'''
a deco to run dymastic method which has a list as first arg
will separate the list into several lists (according to maxThreads) and run them with the method in multi-threads
there is an example under defination
'''
def __init__(self, maxThreads: int = 64):
self.maxThreads = maxThreads
self.groups: list[list] = []
self.threads = []
def separate_groups(self, items):
# init groups
i = 0
while i < self.maxThreads:
self.groups.append([])
i += 1
i = 0
# separate groups
for item in items:
if i == self.maxThreads:
i = 0
self.groups[i].append(item)
i += 1
def __call__(self, func):
@wraps(func)
def group_run(*args, **kwargs):
if type(args[1]) is list:
self.separate_groups(args[1])
for group in self.groups:
argsSep = list(args)
argsSep[1] = group
argsSep = tuple(argsSep)
th = threading.Thread(target=func, args=(argsSep), kwargs=(kwargs))
self.threads.append(th)
for th in self.threads:
th.start()
for th in self.threads:
th.join()
return group_run
import time
class Test:
'''just a sample'''
def __init__(self):
self.result = []
self.lock = threading.Lock()
@ThreadingMask()
def runs(self, items, typeLimit, isNot="a"):
for item in items:
def get_matched():
time.sleep(1)
if type(item) is typeLimit and str(item) != str(isNot):
self.lock.acquire()
self.result.append(item)
self.lock.release()
get_matched()
if __name__ == "__main__":
start = time.time()
a = Test()
bunchOfItems: list = ["d", None, True, "", 1, 2, 3, "a", "b", "c", "this", "e", "d", 13, "p", 0.1, 11]
a.runs(bunchOfItems, str, isNot="b")
a.result.sort()
print(a.result)
b = Test()
b.runs(bunchOfItems, str, isNot="b")
但是RuntimeError:threads can be only started once occurs when the second time call the method with this deco有没有一种方法可以在第二次调用该方法时启动不同的线程,而不是第一次调用的线程?
2条答案
按热度按时间aemubtdh1#
你必须在装饰器对象(ThreadingMask)上创建一个新的线程示例,以在单独的线程中运行,而不是尝试启动同一个线程两次,这是不可能的(你使用的是同一个self.threads对象,你应该在函数上创建新的线程)。
修改的代码示例:
ljsrvy3e2#
我想我得到了答案,我没有在每次调用时重置self.threads = []。
根据[https://stackoverflow.com/questions/27575954/python-decorator-with-arguments-only-called-once],它应该在 Package 的func group_run下