Python的线程阻止了IO操作

时间:2013-04-18 13:32:28

标签: python multithreading python-2.7 io

我有以下问题。每当子线程想要执行某些IO操作(写入文件,下载文件)时,程序就会挂起。在以下示例中,程序挂起opener.retrieve。如果我执行python main.py,则程序在检索功能上被阻止。如果我执行python ./src/tmp.py一切都很好。我不明白为什么。谁能解释我发生了什么?

我在Linux系统上使用python2.7(内核3.5.0-27)。

文件订购:

main.py
./src
    __init__.py
    tmp.py

main.py

import src.tmp

tmp.py

import threading
import urllib

class DownloaderThread(threading.Thread):
    def __init__(self, pool_sema, i):
        threading.Thread.__init__(self)
        self.pool_sema  = pool_sema
        self.daemon     = True
        self.i = i

    def run(self):
        try:
            opener = urllib.FancyURLopener({}) 
            opener.retrieve("http://www.greenteapress.com/thinkpython/thinkCSpy.pdf", "/tmp/" + str(self.i) + ".pdf")
        finally:
            self.pool_sema.release()

class Downloader(object):
    def __init__(self):
        maxthreads             = 1
        self.pool_sema         = threading.BoundedSemaphore(value=maxthreads)

    def download_folder(self):
        for i in xrange(20):
            self.pool_sema.acquire()
            print "Downloading", i
            t = DownloaderThread(self.pool_sema,i)
            t.start()

d = Downloader()
d.download_folder()

1 个答案:

答案 0 :(得分:0)

我设法通过黑客urllib.py让它工作 - 如果你检查它,你会看到许多import语句分散在代码中 - 即它使用导入的东西'即时'而不仅仅是当模块加载时。

所以,真正的原因仍然未知 - 但不值得研究 - 可能是Python导入系统中的一些死锁。你不应该在import期间运行非平凡的代码 - 这只是在寻找麻烦。

如果您坚持,如果将所有这些奇怪的import语句移到urllib.py的开头,就可以使它工作。