2013-08-16 101 views
2

當前的代碼:執行多個線程同時

def export_data(file): 
    <runs the db2 database command to export tables to file> 

def export_to_files(yaml): 
    logger = logging.getLogger("export_to_files") 
    thread1 = threading.Thread(target=export_data, args=[out_file1]) 
    thread1.start() 
    thread2 = threading.Thread(target=export_data, args=[out_file2]) 
    thread2.start() 
    thread1.join() 
    thread2.join() 

def main(): 
    export_to_files() 

if __name__ == "__main__": 
    main() 

我的理解是,只有join()塊調用線程。然而,我沒有意識到thread1.join()甚至會阻止thread2執行,實質上使得代碼僅運行1個線程,即thread1

如何同時執行兩個線程,同時讓主線程等待兩個線程完成?

編輯:我站在糾正,2線程運行,但它似乎只有1線程實際上是「做」的事情在某個時間點。

爲了進一步闡述,callable_method正在從數據庫讀取數據並寫入文件。雖然我現在可以看到2個文件正在更新(每個線程寫入一個單獨的文件),但其中一個文件現在不會更新很長一段時間,而另一個文件是最新的。

沒有正在使用的連接對象。查詢從db2命令行界面運行。

+0

'thread1.join()'不應該阻止'thread2'執行。 –

+0

當你調用它們的'.start()'方法時,線程開始運行。 '.join()'阻塞,直到線程_stops_。 –

+0

你有沒有嘗試刪除join()調用?它應該按照預期執行,如果你這樣做。 – Surveon

回答

0

這說明你的示例代碼可運行版本:

import time 
import threading 

def export_data(fileName): 
    # runs the db2 database command to export tables to file 
    while True: 
     print 'If I were the real function, I would be writing to ' + fileName 
     time.sleep(1) 

thread1 = threading.Thread(target=export_data, args=[ 'out_file1' ]) 
thread2 = threading.Thread(target=export_data, args=[ 'out_file2' ]) 

thread1.start() 
thread2.start() 

thread1.join() 
thread2.join() 
3

你可以使用大部分無證ThreadPoolmultiprocessing.pool沿着這些線路做一些事情:

from multiprocessing.pool import ThreadPool 
import random 
import threading 
import time 

MAX_THREADS = 2 
print_lock = threading.Lock() 

def export_data(fileName): 
    # simulate writing to file 
    runtime = random.randint(1, 10) 
    while runtime: 
     with print_lock: # prevent overlapped printing 
      print('[{:2d}] Writing to {}...'.format(runtime, fileName)) 
     time.sleep(1) 
     runtime -= 1 

def export_to_files(filenames): 
    pool = ThreadPool(processes=MAX_THREADS) 
    pool.map_async(export_data, filenames) 
    pool.close() 
    pool.join() # block until all threads exit 

def main(): 
    export_to_files(['out_file1', 'out_file2', 'out_file3']) 

if __name__ == "__main__": 
    main() 

輸出示例:

[ 9] Writing to out_file1... 
[ 6] Writing to out_file2... 
[ 5] Writing to out_file2... 
[ 8] Writing to out_file1... 
[ 4] Writing to out_file2... 
[ 7] Writing to out_file1... 
[ 3] Writing to out_file2... 
[ 6] Writing to out_file1... 
[ 2] Writing to out_file2... 
[ 5] Writing to out_file1... 
[ 1] Writing to out_file2... 
[ 4] Writing to out_file1... 
[ 8] Writing to out_file3... 
[ 3] Writing to out_file1... 
[ 7] Writing to out_file3... 
[ 2] Writing to out_file1... 
[ 6] Writing to out_file3... 
[ 1] Writing to out_file1... 
[ 5] Writing to out_file3... 
[ 4] Writing to out_file3... 
[ 3] Writing to out_file3... 
[ 2] Writing to out_file3... 
[ 1] Writing to out_file3... 
0

你可見的代碼很好,然而,一些對我們來說不可見的代碼確實使用了鎖定,即使在數據庫本身中也可能發生鎖定。