我想限制活动线程的数量。我所看到的是,一个完成的线程保持活着并且不会自行退出,因此活动线程的数量会一直增长,直到出现错误。
以下代码一次只启动8个线程,但即使完成它们也会保持活动状态。所以数字不断增长:
class ThreadEx(threading.Thread):
__thread_limiter = None
__max_threads = 2
@classmethod
def max_threads(cls, thread_max):
ThreadEx.__max_threads = thread_max
ThreadEx.__thread_limiter = threading.BoundedSemaphore(value=ThreadEx.__max_threads)
def __init__(self, target=None, args:tuple=()):
super().__init__(target=target, args=args)
if not ThreadEx.__thread_limiter:
ThreadEx.__thread_limiter = threading.BoundedSemaphore(value=ThreadEx.__max_threads)
def run(self):
ThreadEx.__thread_limiter.acquire()
try:
#success = self._target(*self._args)
#if success: return True
super().run()
except:
pass
finally:
ThreadEx.__thread_limiter.release()
def call_me(test1, test2):
print(test1 + test2)
time.sleep(1)
ThreadEx.max_threads(8)
for i in range(0, 99):
t = ThreadEx(target=call_me, args=("Thread count: ", str(threading.active_count())))
t.start()
由于for循环,线程数保持增长到99。 我知道一个线程已完成其工作,因为 call_me 已被执行并且 threading.active_count()已被打印。
有人知道我是如何确定的,完成的线程不能保持活着吗?
答案 0 :(得分:0)
这可能是一个愚蠢的答案,但对我来说,你看起来正试图重新发明ThreadPool
。
from multiprocessing.pool import ThreadPool
from time import sleep
p = ThreadPool(8)
def call_me(test1):
print(test1)
sleep(1)
for i in range(0, 99):
p.apply_async(call_me, args=(i,))
p.close()
p.join()
这将确保在任何时间点只有8个并发线程正在运行您的函数。如果您想要更高的性能,可以从多处理中导入Pool
并使用它。接口完全相同,但您的池现在将是子进程而不是线程,这通常会提高性能,因为GIL不会妨碍。
答案 1 :(得分:0)
我根据Hannu的帮助改变了班级。
我发布它以供参考,也许对于遇到这篇文章的其他人有用:
import threading
from multiprocessing.pool import ThreadPool
import time
class MultiThread():
__thread_pool = None
@classmethod
def begin(cls, max_threads):
MultiThread.__thread_pool = ThreadPool(max_threads)
@classmethod
def end(cls):
MultiThread.__thread_pool.close()
MultiThread.__thread_pool.join()
def __init__(self, target=None, args:tuple=()):
self.__target = target
self.__args = args
def run(self):
try:
result = MultiThread.__thread_pool.apply_async(self.__target, args=self.__args)
return result.get()
except:
pass
def call_me(test1, test2):
print(test1 + test2)
time.sleep(1)
return 0
MultiThread.begin(8)
for i in range(0, 99):
t = MultiThread(target=call_me, args=("Thread count: ", str(threading.active_count())))
t.run()
MultiThread.end()
在任何给定时间,线程的最大值为8,由 begin 方法确定。 而且 run 方法返回传递函数的结果,如果返回的话。
希望有所帮助。