web-dev-qa-db-ja.com

2つのpythonループを同時に実行するにはどうすればよいですか?

Pythonで次のように仮定します

# A loop
for i in range(10000):
    Do Task A

# B loop
for i in range(10000):
    Do Task B

これらのループをPythonで同時に実行するにはどうすればよいですか?

21
hiiii

同時実行性が必要な場合は、次の例が非常に簡単です。

from multiprocessing import Process

def loop_a():
    while 1:
        print("a")

def loop_b():
    while 1:
        print("b")

if __name__ == '__main__':
    Process(target=loop_a).start()
    Process(target=loop_b).start()

これは、私が考えることができる最も基本的な例です。何が起こっているのかを理解するには、必ず http://docs.python.org/library/multiprocessing.html を読んでください。

プログラムにデータを送り返す場合は、キューを使用することをお勧めします(これは私の経験では最も使いやすいものです)。

グローバルインタープリターロック を気にしない場合は、代わりにスレッドを使用できます。プロセスはインスタンス化にコストがかかりますが、真の同時実行性を提供します。

27
Stefano Palazzo

なぜ2つのプロセスを同時に実行するのですか?それはあなたが彼らがより速く行くと思うからです(彼らがしない可能性が高いです)。同じループでタスクを実行してみませんか。

for i in range(10000):
    doTaskA()
    doTaskB()

あなたの質問に対する明白な答えは、スレッドを使用することです-python threading モジュールを参照してください。ただし、スレッド化は大きなテーマであり、多くの落とし穴があるため、前に読んでくださいあなたはそのルートを下ります。

または、python multiprocessing モジュールを使用して、タスクを別々のプロセスで実行することもできます。両方のタスクがCPUを集中的に使用する場合、これにより、コンピューター上の複数のコアをより効率的に使用できます。

コルーチン、スタックレスタスクレット、グリーンレット、CSPなどの他のオプションもありますが、タスクAとタスクBについての詳細と、それらを同時に実行する必要がある理由を知らないと、より具体的な答えを出すことができません。

13
Dave Kirby

あなたが望むもののための多くの可能なオプションがあります:

ループを使用

多くの人が指摘しているように、これが最も簡単な方法です。

for i in xrange(10000):
    # use xrange instead of range
    taskA()
    taskB()

メリット:理解と使用が簡単で、追加のライブラリは必要ありません。

欠点:taskBはtaskAの後に実行する必要があります。同時に実行することはできません。

マルチプロセス

もう1つの考えは、2つのプロセスを同時に実行する、pythonが提供する マルチプロセスライブラリ です。以下は簡単な例です。

from multiprocessing import Process


p1 = Process(target=taskA, args=(*args, **kwargs))
p2 = Process(target=taskB, args=(*args, **kwargs))

p1.start()
p2.start()

メリット:タスクはバックグラウンドでsimultaneouslyを実行でき、タスクを制御(終了、停止など)できます。タスクはデータを交換でき、同じリソースと競合する場合は同期できます。

欠点:重すぎる!OSは頻繁にそれらを切り替え、データが冗長であっても独自のデータ領域を持っています。たくさんのタスク(たとえば100以上)がある場合、それはあなたが望むものではありません。

スレッディング

スレッド化はプロセスのようなもので、軽量です。チェックアウト この投稿 。それらの使い方は非常に似ています:

import threading 


p1 = threading.Thread(target=taskA, args=(*args, **kwargs))
p2 = threading.Thread(target=taskB, args=(*args, **kwargs))

p1.start()
p2.start()

コルーチン

greenletgeventなどのライブラリは、コルーチンと呼ばれるものを提供します。これは、スレッド化よりも高速であると想定されています。例は提供されていません。興味がある場合は、それらの使用方法をググってください。

メリット:より柔軟で軽量

欠点:追加のライブラリが必要、学習曲線。

10
cizixs
from threading import Thread
def loopA():
    for i in range(10000):
        #Do task A
def loopB():
    for i in range(10000):
        #Do task B
threadA = Thread(target = loopA)
threadB = Thread(target = loobB)
threadA.run()
threadB.run()
# Do work indepedent of loopA and loopB 
threadA.join()
threadB.join()
8
Odomontois

方法:範囲(10000)内のiのループ:タスクAを実行し、タスクBを実行しますか?より多くの情報がなければ、私はより良い答えはありません。

1
PeterK

threading または multiprocessing を使用できます。

1
Matt Curtis

「multiprocessing」内の「pool」サブモジュールを使用すると、Python Script。

セクション:ワーカーのプールの使用を参照

例の「#複数の評価を非同期で起動するmay使用するプロセス」を注意深く確認してください。これらの行が何をしているのかを理解したら、私が作成した次の例は非常に理にかなっています。

import numpy as np
from multiprocessing import Pool

def desired_function(option, processes, data, etc...):
    # your code will go here. option allows you to make choices within your script
    # to execute desired sections of code for each pool or subprocess.

    return result_array   # "for example"


result_array = np.zeros("some shape")  # This is normally populated by 1 loop, lets try 4.
processes = 4
pool = Pool(processes=processes)
args = (processes, data, etc...)    # Arguments to be passed into desired function.

multiple_results = []
for i in range(processes):          # Executes each pool w/ option (1-4 in this case).
    multiple_results.append(pool.apply_async(param_process, (i+1,)+args)) # Syncs each.

results = np.array(res.get() for res in multiple_results)  # Retrieves results after
                                                           # every pool is finished!

for i in range(processes):
    result_array = result_array + results[i]  # Combines all datasets!

コードは基本的には、設定された数のプロセスに必要な関数を実行します。関数が各プロセスを区別できるように注意深く確認する必要があります(そのため、変数 "option"を追加した理由です)。さらに、最後に入力される配列である必要はありませんが、私の例では、それは私がそれを使用した方法です。これがPythonのマルチプロセッシングの力を単純化または理解するのに役立つことを願っています!

0