2015-10-15 50 views
0

在我的python代碼中,我調用外部api來獲取圖像的url列表。對於這些網址中的每一個,我創建一個線程來生成縮略圖。這裏是感興趣的部分代碼:Python線程隊列和無響應線程

def process_image(image, size, cropping, counter, queue): 
    options = dict(crop=cropping) 
    img = get_thumbnail(image['url'], size, **options) 
    queue.put((counter, img)) 
    return img 

... 

queue = Queue() 

# Get some information about an artist. Images are also included. 
artist = get_profile(artist_id, buckets) 

# Generate images' thumbnails 
threads = [Thread(target=process_image, args=(img, '500', 'center', counter, queue)) for counter, img in enumerate(artist.data['images'])] 

for p in threads: 
    p.start() 
for p in threads: 
    p.join() 

imgs = [] 
# Collect processed images from threads 
while not queue.empty(): 
    el = queue.get() 
    imgs.append((el[0], el[1])) 

我的問題是,一些網址不工作,我的意思是,如果我複製粘貼在瀏覽器的URL它不斷載荷和載荷並加載多一點,直到返回超時。很明顯,我添加了多線程來加快速度。導致此問題的第一個URL是4,所以如果我加入...

# Generate images' thumbnails 
threads = [Thread(target=process_image, args=(img, '500', 'center', counter, queue)) for counter, img in enumerate(artist.data['images'])] 
treads = threads[:3] 

一切正常,並很快,否則它就會被阻塞很長一段時間,它終於終止執行。我想爲線程運行該函數設置某種超時(比如說1秒),如果url不起作用,並且線程在超時之前沒有完成,那麼退出該線程。

非常感謝您的幫助。

+2

看起來像你應該有超時作爲URL請求的一部分,而不是讓線程負責殺死自己,如果它需要太長時間。有沒有辦法在你使用的這個庫中執行超時? – turbulencetoo

+0

我還記得python中的多線程通常不會加快速度,因爲任何時候只有一個線程可以由解釋器執行。請參閱https://wiki.python.org/moin/GlobalInterpreterLock – turbulencetoo

+0

@turbulencetoo對於讓url請求超時有一點意見。我更熟悉'多處理'與'線程',但不會「連接」採取可選的超時參數?另外,如果您有多個CPU,使用多處理功能將使您能夠真正並行運行。 – RobertB

回答

0

如果get_thumbnail函數是你的,我會像@turbulencetoo建議的那樣建立超時。否則,請查看signal模塊以在process_image中添加超時。正如評論中所建議的那樣,您可能還會看到使用多處理與線程的進一步優勢。多處理模塊的接口與線程的接口幾乎相同,因此切換時不需要太多工作。

0

正如other questions所述,在Python中沒有官方的方式來終止線程。在線程正在執行您控制的工作(而不是阻止例如網絡請求)的情況下,您可以使用信號變量讓線程自殺,但這似乎不是這種情況。

對於並行下載多個資源,您可能要使用像pycurl這樣的庫,它將使用特定於操作系統的功能來允許多個請求在單個線程上異步執行。這可以讓你使用像set_timeout這樣的方法,它提供了一個相當乾淨的方式來處理你描述的問題。

0

我終於找到了基於@ turbulencetoo評論的解決方案。

get_thumbnail不是我的代碼的一部分,而是一個外部庫,所以我無法在代碼中設置任何類型的超時。我認爲這個庫沒有配置項目來設置URL請求期間的超時,但顯然有(我已經閱讀了它,我誤解了)。

@RobertB是的,join()有一個超時參數,我已經嘗試設置該參數,但它沒有工作。