簡體   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