2013-04-18 142 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的開頭,就可以使其工作。