兼務(はじめに)
プロセスまたはスレッドの使用。
同時進行(理解)
【スレッド処理の違い】
-
スレッドは共有メモリ空間です。
-
プロセスはメモリに依存しません。
同じプロセス内のスレッドは相互に直接通信できます。
2 つのプロセスが通信したい場合は、中間エージェントを経由する必要があります。
マルチスレッドを使用するとCPUを最大限に活用でき、プログラムの実行効率が向上します。
各プロセスが開始されると、最初にメインスレッドであるスレッドが作成され、次にメインスレッドが他の子スレッドを作成します。
プロセスには複数のスレッドを含めることができます。
【同期・非同期】
同期する | タスクを送信した後、次のコード行を実行する前に、タスクが実行される (戻り値を取得する) まで待つ必要があります。 タスクのシリアル実行に相当します。 |
非同期 | タスクを引き渡した後、実行が完了するのを待たずに、コードの次の行を直接実行できます。 |
同時実行 (パラメータリスト)
同時先物 |
このモジュールは、高度にカプセル化された非同期呼び出しインターフェイスを提供します。 |
スレッドプールエグゼキュータ |
スレッド プール、非同期呼び出しを提供する |
プロセスプールエグゼキュータ |
プロセス プール、非同期呼び出しを提供する |
サブプロセス |
サブプロセス操作 |
結果(タイムアウト=なし) |
結果を得る |
add_done_callback(fn) |
折り返し電話 |
submit(fn, *args, **kwargs) |
タスクを非同期で送信する |
待つ=真 |
続行する前に、プール内のすべてのタスクが実行され、リソースが再利用されるまで待ちます。 |
待機=False |
すぐに戻り、プール内のタスクが完了するのを待ちません。 ただし、wait パラメータの値に関係なく、プログラム全体はすべてのタスクが完了するまで待機します。 |
シャットダウン(待機=True) |
プロセス プールの pool.close()+pool.join() 操作と同等 |
map(func, *iterables, timeout=None, chunksize=1) |
for ループの送信操作を置き換えます。 |
同時実行(参照コード)
シンプルなマルチスレッド操作
from concurrent.futures import ThreadPoolExecutor
import time
def task(i):
print(f"在执行任务{i}")
print("假设这是一个URL请求的地址....")
time.sleep(5)
pool = ThreadPoolExecutor(2) # 4个线程
for i in range(20):
pool.submit(task, i)
前の例の簡易バージョン (マップ)
# 例子-map用法
from concurrent.futures import ThreadPoolExecutor
from threading import Thread, currentThread
import time
def task(i):
print(f"{currentThread().name} 在执行任务{i}")
time.sleep(1)
if __name__ == "__main__":
pool = ThreadPoolExecutor(4)
pool.map(task, range(0, 20)) # map取代了for+submit
マルチプロセッシング (はじめに)
プロセスの高度な使用法。
マルチプロセッシング (理解)
multiprocessing-module は、子プロセスを開始するために使用されます。
機能: 子プロセスのサポート、データの通信と共有、さまざまな実行の同期の実行。
提供 -> プロセス、キュー、パイプ、ロック、その他のコンポーネント。
マルチプロセッシング(パラメータリスト)
プロセスクラス |
|
このクラスによってインスタンス化されたオブジェクトは、子プロセスを開始するために使用できます。 [構文] Process([グループ [, ターゲット [, 名前 [, args [, kwargs]]]]]) group パラメータ (今のところ無視されています) は使用されず、値は常に None です。 target (関数) は呼び出し元のオブジェクト、つまり子プロセスによって実行されるタスクを表します。 args (関数パラメーター) は、呼び出し元オブジェクトの位置パラメーター タプル、args=(1,2,'mike') を表します。 kwargs (今のところ無視されます) は、呼び出し元オブジェクトの辞書、kwargs={'name':'mike','age':'18'} を表します。 |
よく使われる機能 |
|
始める() |
(プロセスの開始) サブプロセス内で run() を呼び出します。 |
走る() |
(プロセス起動時に実行されるメソッド) targetで指定した関数を呼び出すものです。 |
終了() |
(プロセスを強制終了)、クリーニング操作は実行されません。子プロセスが作成されると、 子プロセスがゾンビプロセスになるため、この方法を使用する場合は特に注意が必要です。 ロックがまだ保存されている場合は解放されず、デッドロックが発生します。 |
生きている() |
プロセスはまだ実行中であり、True を返します。 |
join([タイムアウト]) |
メインプロセスが終了待ち中(メインプロセスが待ち状態) |
デーモン |
デフォルト値は False で、True に設定すると、子プロセスがバックグラウンドで実行されるデーモン プロセスであることを意味します。 親プロセスが終了すると、子プロセスも終了し、True に設定されます。 |
名前 |
プロセス名 |
ピド |
プロセスID |
マルチプロセッシング(参考コード)
単一プロセス
import multiprocessing
import time
def func(msg):
for i in range(20):
print(msg, i)
time.sleep(1)
if __name__ == "__main__":
p = multiprocessing.Process(target=func, args=("input content....",))
p.start()
p.join()
print("Sub-process done.")
マルチプログレス
import multiprocessing
import time
def fc1(msg):
for i in range(3):
print("{}:黄岛主 正在进行任务{}....".format(msg, i + 1))
time.sleep(1)
print(">>>>>> {}大佬 任务完成".format(msg))
def fc2(msg):
for i in range(2):
print("{}:欧阳锋 正在进行任务{}....".format(msg, i + 1))
time.sleep(1)
print(">>>>>> {}大佬 任务完成".format(msg))
def fc3(msg):
for i in range(5):
print("{}:段大师 正在进行任务{}....".format(msg, i + 1))
time.sleep(1)
print(">>>>>> {}大佬 任务完成".format(msg))
def fc4(msg):
for i in range(2):
print("{}:洪七公 正在进行任务{}....".format(msg, i + 1))
time.sleep(1)
print(">>>>>> {}大佬 任务完成".format(msg))
if __name__ == "__main__":
pool = multiprocessing.Pool(processes=4) # CPU核数
result = []
person = ["东邪", "西毒", "南帝", "北丐"]
result.append(pool.apply_async(fc1, (person[0],)))
result.append(pool.apply_async(fc2, (person[1],)))
result.append(pool.apply_async(fc3, (person[2],)))
result.append(pool.apply_async(fc4, (person[3],)))
pool.close()
pool.join()
print("全部OK....")
マルチスレッドキュー
import multiprocessing as mp
def job(x):
res = 0
for i in range(4):
res += i
x.put(res)
if __name__ == "__main__":
# 定义一个多线程队列,用来存储结果
q = mp.Queue()
# 定义两个线程函数,用来处理同一个任务
# Process / Thread
p1 = mp.Process(target=job, args=(q,))
p2 = mp.Process(target=job, args=(q,))
# 分别启动、连接两个线程
p1.start()
p2.start()
p1.join()
p2.join()
fc1 = q.get()
fc2 = q.get()
print(fc1 + fc2)
プロセスロック
# 防止不同进程之间抢占共享资源
import multiprocessing as mp
import time
def job(v, num, l):
l.acquire() # 锁住
for _ in range(5):
time.sleep(1)
v.value += num # 获取共享内存
print("value=", v.value)
l.release() # 释放
def multicore():
lock = mp.Lock() # 定义一个进程锁
value = mp.Value("i", 20) # 定义共享内存
p1 = mp.Process(target=job, args=(value, 1, lock)) # 需要将lock传入
p2 = mp.Process(target=job, args=(value, 3, lock))
p1.start()
p2.start()
p1.join()
p2.join()
if __name__ == "__main__":
multicore()