在Python中,线程和tempfile模块有一个有趣的问题。在线程退出之前,某些东西似乎不会被清理干净,而我正在违反打开文件的限制。(这是在OS X 10.5.8和Python 2.5.1上安装的。)
但是如果我复制tempfile模块正在做的事情(不是所有的安全检查,而是生成一个文件描述符,然后使用os.fdopen操作系统产生一个文件对象)我没有问题。在
在把它作为一个bug提交给Python之前,我想我应该在这里检查一下,因为很可能我做了一些微妙的错误。但如果我是的话,一天的努力也没有让我有任何收获。在
#!/usr/bin/python
import threading
import thread
import tempfile
import os
import time
import sys
NUM_THREADS = 10000
def worker_tempfile():
tempfd, tempfn = tempfile.mkstemp()
tempobj = os.fdopen(tempfd, 'wb')
tempobj.write('hello, world')
tempobj.close()
os.remove(tempfn)
time.sleep(10)
def worker_notempfile(index):
tempfn = str(index) + '.txt'
# The values I'm passing os.open may be different than tempfile.mkstemp
# uses, but it works this way as does using the open() function to create
# a file object directly.
tempfd = os.open(tempfn,
os.O_EXCL | os.O_CREAT | os.O_TRUNC | os.O_RDWR)
tempobj = os.fdopen(tempfd, 'wb')
tempobj.write('hello, world')
tempobj.close()
os.remove(tempfn)
time.sleep(10)
def main():
for count in range(NUM_THREADS):
if count % 100 == 0:
print('Opening thread %s' % count)
wthread = threading.Thread(target=worker_tempfile)
#wthread = threading.Thread(target=worker_notempfile, args=(count,))
started = False
while not started:
try:
wthread.start()
started = True
except thread.error:
print('failed starting thread %s; sleeping' % count)
time.sleep(3)
if __name__ == '__main__':
main()
如果我在worker_notempfile
行处于活动状态并且worker_tempfile
行被注释掉的情况下运行它,它将运行到完成状态。在
另一种方法(使用worker_tempfile
)得到以下错误:
你知道我做错了什么吗?这是Python中的一个bug,还是我有点头晕目眩?在
更新2009年12月14日: 我想我找到了答案,但我不喜欢。因为没人能复制这个问题,我就到处找机器。除了我的机器什么都没用。我在一台Mac电脑上测试了我使用的软件版本。我甚至去寻找一个桌面G5,它的硬件和软件配置和我完全一样——结果是一样的。两个测试(有tempfile和没有tempfile)都成功了。在
为了获得成功,我下载了Python2.6.4,并在桌面上进行了尝试,在我的系统上使用了与Python2.5.1相同的模式:tempfile失败,notempfile成功。在
这让我得出结论:我的Mac电脑上有东西,但我肯定搞不清是什么。欢迎提出任何建议。在
我无法在MacOSX10.5.9上用(苹果自己构建的)Python2.5.1来重现这个问题——运行起来很好!在
我在MacBookPro(即英特尔处理器)和旧PowerMac(即PPC处理器)上都试过。在
所以我只能想象在10.5.8中一定有一个我从未注意到的bug(没有任何10.5.8可以测试,因为每当软件更新提供时,我总是迅速升级)。我只能建议你升级到10.5.9版本,看看这个bug是否消失了——如果没有,我不知道我的机器和你的机器之间的行为差异是怎么可能的。在
我想你的答案可以找到。您必须显式地
os.close()
作为mkstemp
提供的元组的第一部分给出的文件描述符。在编辑:不,手术室已经在做该做的事了。我把答案留到好的链接上。在
我刚刚在我的Ubuntu Linux电脑上测试了你的代码,它对我来说非常好。在
我有一个建议你试试。我不知道这会不会有帮助,但不会受伤。重写代码以用于:
with
语句应该确保无论发生什么情况,file对象都会被关闭。也许会有帮助?在祝你好运。顺便问一句,很好。在
相关问题 更多 >
编程相关推荐