

スレッドはthreadingでメソッドを複数生成して、ほぼ並列処理みたいな感じというのはなんとなくわかったのですが、メソッドの戻り値がほしいときは、どのようにしてとったらよいのでしょうか？理想は全ての戻り値を足すことができればと思っているのですが・・・

まず考え方が間違っているのでしょうか？

[code]

    def pulus(x, y):
        sums = x + y
        return sums
    
    pulus_threads = []
    for i in range(1, 3):
        pulus_thread = threading.Thread(target=pulus, args=(i, i))
        pulus_threads.append(pulus_thread)
        pulus_thread.start()
    for pulus_thread in pulus_threads:
        pulus_thread.join()
    
[/code]


CC BY-SA 3.0
2017-12-03T17:57:02.320
40007
2018-03-30T06:40:49.157
26076
question
python
pythonのマルチスレッドのメソッドから戻り値を得るにはどうしたらよいですか？


"python multithread return value"で検索すると、色々と出てきます。  
英語版のStackOverflowにいくつか良さそうなのがありました。

1.multiprocessingモジュールのThreadpoolを使う方法  
ベストアンサーではapply_asyncでスレッドプールを作成し、getで結果を取得しています。  
ただし、ベストアンサーについても、色々と議論の余地があるようです。  
how to get the return value from a thread in python?  
<https://stackoverflow.com/questions/6893968/how-to-get-the-return-value-from-
a-thread-in-python>  
関連  
How to obtain the results from a pool of threads in python?  
<https://stackoverflow.com/questions/26104512/how-to-obtain-the-results-from-
a-pool-of-threads-in-python/26104609#26104609>

2.QueueモジュールのQueueを使う方法  
ベストアンサーでは先にQueueを作成し、各スレッドのパラメータにそのQueueを指定し、スレッドは結果をQueueに詰める。  
呼び出し元はすべてのスレッドが終了してからQueueの結果が無くなるまで合計なり平均なりのやりたい処理を行う。  
こちらも議論の余地があるようです。  
Return value from thread  
<https://stackoverflow.com/questions/1886090/return-value-from-thread>

3.参考  
pythonのモジュールに関する解説サイトから  
threading – Manage concurrent threads  
<https://pymotw.com/2/threading/>  
multiprocessing — Manage Processes Like Threads  
<https://pymotw.com/3/multiprocessing/index.html>


CC BY-SA 3.0
2017-12-03T23:45:31.400
40010
2017-12-03T23:45:31.400
26370
40007
answer


用途によりけりなのですが、今回の場合は`concurrent.futures`の[`ThreadPoolExecutor`](https://docs.python.org/3/library/concurrent.futures.html#executor-
objects)を使うと楽に実装できます。

[code]

    from concurrent.futures import ThreadPoolExecutor
    
    def pulus(x, y):
        sums = x + y
        return sums
    
    with ThreadPoolExecutor(max_workers=10) as executor:
        x = range(5)
        y = range(5, 10)
        res = executor.map(pulus, x, y)
    
    
    print(list(x))
    print(list(y))
    print(list(res))
    
[/code]

`ThreadPoolExecutor`はI/Oがボトルネックのときによく使われます。重い処理を複数のCPUに分散させることが目的でしたら、`ProcessPoolExecutor`のほうがいいかもしれません。


CC BY-SA 3.0
2017-12-04T04:32:00.700
40016
2017-12-04T04:32:00.700
26311
40007
answer