繁体   English   中英

Python错误“无法启动新线程”,但是没有其他线程在运行

[英]Python error “can't start new thread”, but there are no other threads running

我有一个用Python 2.7编写的守护程序,它的工作原理如下:

1-脚本启动4个线程

2-4个线程同时在做一些工作

3-脚本使用thread.join()等待所有线程完成

循环4-1-3

用伪代码看起来像:

formatter = logging.Formatter('%(threadName)s : %(message)s')
# (... logging setup ...)
def doSomeWork(item):
    log.debug('Doing some work with item %s', item)
    # (... doing some work ...)
itemList = [some, items, thatProgram, worksWith]
while True:
    threads = []
    for item in itemList:
        if someComplexConditionCheck:
             threads.append(threading.Thread(target=doSomeWork, args=(item,))
    for thread in threads:
        thread.start()
    for thread in threads:
        thread.join()
    time.sleep(10)

(当然,实际程序要复杂得多)(实际的doSomeWork代码可能会启动其他一些线程,但它也使用thread.join()等待完成)。 主while(true)循环永远不会继续,直到所有先前的线程完成。

几天后,我的程序因“错误:无法启动新线程”而崩溃。 日志中的最后一条记录对应于线程15027,如下所示:

Thread-15027 Doing some work

我查找了stackoverflow,但是发现的所有建议都是使用命令ps -fLu UserName一次检查运行的线程数。 我看到在检查时只有线程在运行,因此由于加入命令,旧线程总是在开始新线程之前就已完成。

我认为,问题可能出在大型线程ID(15027)中,该线程ID在每次调用Thread构造函数后都会增加。 (我是对的吗?)但是我不知道如何重置它,而是每天使用crontab重新启动守护程序,但这是一个非常肮脏的技巧。

由于问题与线程创建没有直接关系,因此您可以检查内存是否用完了吗? 这似乎是最有可能的罪魁祸首。 但是,无论原因如何,一种验证方法是在strace下运行您的应用并查找ENOMEM错误或任何其他错误。

我最初的想法是让您的应用检查可用内存,但是从该应用检查内存非常棘手,因为操作系统有时会使用大量可用内存,然后在应用需要时放弃它。

strace -o app_strace.log python app.py myarg1 myarg2

如果发生错误,POSIX系统调用通常返回-1,因此您可以grep日志文件

grep“ \\ = -1” app_strace.log

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM