2013-04-18 69 views
0

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

我在Linux系统上使用python2.7(kernel 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() 

回答

0

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

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

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