2011-11-23 117 views
15

我使用python 2.7,我有一些代碼,看起來像這樣:執行任務蟒蛇

task1() 
task2() 
task3() 
dependent1() 

task4() 
task5() 
task6() 
dependent2() 

dependent3() 

的唯一依賴性這裏如下:dependent1需要等待tasks1-3,dependent2需求等待任務4-6和依賴3需要等待依賴者1-2 ......以下內容可以:先並行運行整個6個任務,然後並行地運行前兩個依賴者..然後最終依賴

我更喜歡儘可能多的任務並行運行,我爲一些模塊搜索了一些內容,但我希望避免使用外部庫,並且不確定Que ue-Thread技術可以解決我的問題(也許有人可以推薦一個好的資源?)

+0

我推薦使用標準庫的* Queue.task_done *和* Queue.join *方法來同步這些線程。在隊列文檔的頁面底部,您會找到一個如何等待其他線程完成其任務的示例:http://docs.python.org/library/queue.html#Queue.Queue.join –

+0

如果你的代碼變得更加複雜,那麼值得看看外部庫,因爲已經有事情需要處理並行運行任務,同時確保依賴性按順序運行。 –

+0

由於GIL,線程將只在標準python中一次運行一個線程。使用STM的Pypy的未來版本可能會得到這個。 –

回答

24

內置threading.Thread類提供您所需的全部內容:start開始一個新線程並且join等待線程結束。

import threading 

def task1(): 
    pass 
def task2(): 
    pass 
def task3(): 
    pass 
def task4(): 
    pass 
def task5(): 
    pass 
def task6(): 
    pass 

def dep1(): 
    t1 = threading.Thread(target=task1) 
    t2 = threading.Thread(target=task2) 
    t3 = threading.Thread(target=task3) 

    t1.start() 
    t2.start() 
    t3.start() 

    t1.join() 
    t2.join() 
    t3.join() 

def dep2(): 
    t4 = threading.Thread(target=task4) 
    t5 = threading.Thread(target=task5) 

    t4.start() 
    t5.start() 

    t4.join() 
    t5.join() 

def dep3(): 
    d1 = threading.Thread(target=dep1) 
    d2 = threading.Thread(target=dep2) 

    d1.start() 
    d2.start() 

    d1.join() 
    d2.join() 

d3 = threading.Thread(target=dep3) 
d3.start() 
d3.join() 

或者加入,您可以使用Queue.join等待線程結束。

+1

這太棒了!但我的任務函數返回的是我在dep函數中使用的值,我如何從t1,t2,t3等獲取返回的值。 –

+2

首先打在SO給我http://stackoverflow.com/questions/1886090/return-value-from-thread – gecco

+0

如果我想傳遞一些參數到該函數? – Lavish

2

看看Gevent

實例應用:

import gevent 
from gevent import socket 

def destination(jobs): 
    gevent.joinall(jobs, timeout=2) 
    print [job.value for job in jobs] 

def task1(): 
    return gevent.spawn(socket.gethostbyname, 'www.google.com') 

def task2(): 
    return gevent.spawn(socket.gethostbyname, 'www.example.com') 

def task3(): 
    return gevent.spawn(socket.gethostbyname, 'www.python.org') 

jobs = [] 
jobs.append(task1()) 
jobs.append(task2()) 
jobs.append(task3()) 
destination(jobs) 

希望,這是你一直在尋找的東西。

+2

真的嗎? OP要求使用隊列/線程技術的多線程解決方案,並希望避免外部庫。但是,您將他指向一組外部依賴關係,並忽略標準庫提供的基本解決方案。 –

+2

點好了。 – meson10