gpt4 book ai didi

Python 线程似乎无缘无故停止/卡住/挂起?可能的原因?

转载 作者:太空宇宙 更新时间:2023-11-04 10:32:19 26 4
gpt4 key购买 nike

在我看来,线程无缘无故地突然停止执行,并且再也不会恢复或重新启动。这种行为的可能原因是什么?不会抛出异常。至少没有检测到或打印异常。它只是在没有任何信息的情况下停止。我的 pygtk GUI 和其他一切继续运行没有问题。

它仅限于一段代码,但它发生在该段内的任何地方。以下代码在该线程内运行。我在我的代码中插入了很多打印件,因为我无法调试它。调试器也卡住了。并且在没有调试器的情况下运行不会改变它(所以它不是调试的一些副作用)

count = 0
while True:
count = count + 1
#read results calculated by another thread. Done via Queue.Queue
pos, phrase, site, extractor, infoextractor, image = self.htmlqueue.get(True)
print "\"", threading.currentThread(), "\"", site, image["link"], infoextractor.__class__.__name__ , FileDownloader.nbdownloads, count
print "1"
#if Nones are found in the queue it means that there will be no more data
if pos is None and phrase is None and site is None and extractor is None and infoextractor is None and image is None: break
print "2"
if printstuff: print "preDownloadAll1", image["link"],
print "3"
try:
info = infoextractor.extractValues()
print info
except (object) as e:
print "exception!"

print "5"
if info is None:
print "_5.1_"
continue
print "6"
if len(info) == 0:
print "_6.1_"
continue
print "7"

if "google" in site:
print "8"
adr = image["smallthumb"]
filename = ImageManager.extractFileFromURL(image["smallthumb"])
elif info.has_key("thumb"):
print "9"
adr = info["thumb"]
filename = ImageManager.extractFileFromURL(info["thumb"])
else:
print "10"
adr = image["thumb"]
filename = ImageManager.extractFileFromURL(image["thumb"])
print "11"
localfile = self.imagelocations[site] + "/" + filename
print "12"
t = None
if (not os.path.isfile(localfile)) and predownloadjpegs:
print "13"
t = FileDownloader.downloadFileNewThread(url = adr, localtargetdir = self.imagelocations[site], timetofinish = 100)
print "14"
tds.append((t, pos, phrase, site, extractor, infoextractor, image, info, adr, localfile))
print "15"
if count%100 == 0: print count, "\n"
print "16"
# seen[image["link"]] = True
print "17"

代码平均运行大约 3000-5000 次计数,并在不同的队列条目处停止(大部分 html 已缓存 ;))。挂起前的最后输出 是随机的(每次我重新启动我的应用程序时它都不同)。大多数时候是 3,有时是 16。永远不会达到 17。我也有一个 7。另一次它打印了信息,但它不再打印 5。还有一次它打印了一半的信息字符串。

因为大部分时间是 3,我怀疑那里有异常,也许是一些非常奇怪的延迟检测。但不是!打印“异常!”在我的测试期间从未执行过。

我的线程在卡住后仍保留在内存中并且不会阻塞

self.htmlqueue.get(True)

因为如果我这样做

pos, phrase, site, extractor, infoextractor, image = None, None, None, None, None, None
success = False
while not success:
try:
pos, phrase, site, extractor, infoextractor, image = self.htmlqueue.get(True,10)
success = True
except:
print "no success", count
success = False

然后卡住继续,在大多数运行中根本没有“不成功”的输出。更糟糕的是,我使用信号量一次运行一个代码段,因此所有其他线程都被阻塞并等待这个线程完成。

主 GUI 线程继续运行而不受干扰。我自己的所有线程都应该在执行后死亡(我用 mythread.setDaemon(True) 对它们进行了 deamonized)。我的python版本是2.7.3

我也在考虑输出缓冲区的可能性,它只会使它随机出现(实际上它总是在同一个地方,但一些输出可能仍然在输出缓冲区中徘徊)但是由于每次打印都会引入一个新行,我猜每个输出都会立即刷新,所以我不会错过线程卡住点的任何输出。我的开发环境是eclipse和pydev。

FileDownloader.downloadFileNewThread 从该线程内部启动另一个线程。这也会是个问题吗?线程启动其他线程?如果我不妖魔化与如果我妖魔化似乎也没有什么区别。

在我看来,代码确实随机卡住。但为什么会这样???

最佳答案

好的伙计们,经过 3 天的用头撞墙,我想我已经解决了。至少没有东西挂了。

Pygtk 好像是这个原因 http://faq.pygtk.org/index.py?file=faq20.006.htp&req=show

Pygtk 能够永远阻塞长时间运行的线程。它获得了 GIL 锁并且不松手。该线程只是卡在内存中,但不会再执行。

我所要做的就是打电话

gobject.threads_init()

在其他与 gtk 相关的事情之前。也就是说,我的代码是这样开始的

import gtk
import gobject
import MainGUI

if __name__ == "__main__":
gobject.threads_init()
from MainGUI import MainGUI
MainGUI.instance = MainGUI()
gtk.main()

幸运的是,我严格地将我的逻辑与 GUI 分开,并且从不在我自己的线程中实例化任何 gtk 元素。所以这是我真正需要的唯一一行。如果有人仍然需要能够在自己的线程中处理 GUI 对象,他必须使用

gobject.idle_add(callback_function, args)

我学到的另一个教训是,队列的内存容量可能非常有限,如果它们被塞得太多,它们也会导致阻塞行为。

Theads 启动另一个线程应该没有任何问题,因为据我所知,这些线程都是“在同一级别”启动的,python 不知道或维护它们之间的任何层次结构。 pygtk 搞砸的只是 GIL(全局解释器锁)的伪随机斗争。

关于Python 线程似乎无缘无故停止/卡住/挂起?可能的原因?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25731113/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com