You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用threading库及Semaphore仍遇RuntimeError: Can't start new thread问题

解决RuntimeError: Can't start new thread的问题

我之前踩过一模一样的坑!你说的完全没错——threading.Semaphore(4)只能控制同时运行的线程数量,但如果你一次性把1000个Thread对象都创建出来并调用start(),系统的线程资源还是会被瞬间耗尽,毕竟Semaphore只是让后面的线程等着,可线程本身已经被创建出来了,这才是报错的根源。

给你两个靠谱的解决方案:

方案一:用线程池(最推荐)

Python的concurrent.futures.ThreadPoolExecutor是专门用来处理这种场景的,它会帮你自动管理线程的创建、复用和销毁,不会一次性创建所有线程。比如设置max_workers=4,系统里最多只会存在4个线程,任务会被放到内部队列,线程空闲了就去取新任务执行。

举个实际的代码例子:

from concurrent.futures import ThreadPoolExecutor

def process_task(task):
    # 这里写你的任务处理逻辑,比如:
    print(f"Processing task {task}")

if __name__ == "__main__":
    # 1000个任务也完全没问题
    task_list = range(0, 1000)
    
    # 初始化线程池,最多4个并发线程
    with ThreadPoolExecutor(max_workers=4) as executor:
        # 把任务映射到线程池执行
        executor.map(process_task, task_list)

这种写法不仅简洁,还能避免手动管理线程的麻烦,完全解决线程数量过载的问题。

方案二:手动用队列控制线程创建(如果坚持用threading模块)

如果你不想用线程池,也可以手动实现“固定数量线程+任务队列”的模式:只创建4个工作线程,让它们从队列里不断取任务执行,直到所有任务处理完毕。这样系统里始终只有4个线程,不会出现创建1000个线程的情况。

代码示例:

import threading
from queue import Queue

def worker_thread(task_queue):
    while True:
        # 从队列取任务,取不到就阻塞
        task = task_queue.get()
        # 用None作为终止信号,收到就退出线程
        if task is None:
            break
        # 执行任务逻辑
        process_task(task)
        # 告诉队列这个任务处理完了
        task_queue.task_done()

def process_task(task):
    print(f"Processing task {task}")

if __name__ == "__main__":
    task_queue = Queue()
    max_workers = 4
    
    # 把所有任务放到队列里
    for task in range(0, 1000):
        task_queue.put(task)
    
    # 创建并启动4个工作线程
    threads = []
    for _ in range(max_workers):
        t = threading.Thread(target=worker_thread, args=(task_queue,))
        t.start()
        threads.append(t)
    
    # 等待队列里所有任务都处理完
    task_queue.join()
    
    # 给每个线程发终止信号
    for _ in range(max_workers):
        task_queue.put(None)
    
    # 等待所有线程结束
    for t in threads:
        t.join()

再补充下为什么之前的Semaphore没用

你之前的写法应该是循环创建1000个Thread,然后每个线程里先semaphore.acquire(),执行任务后再release()。这种情况下,1000个线程其实都已经被创建并启动了,只是大部分在阻塞等待Semaphore的许可,系统的线程数量还是1000,远超系统能承载的上限(一般系统默认的线程数上限在几百左右),所以才会抛出Can't start new thread的错误。

内容的提问来源于stack exchange,提问作者jo2083248

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:24:54