Python__module(TIME-プロセス/スレッド)__同時実行/マルチプロセス

兼務(はじめに)

プロセスまたはスレッドの使用。


同時進行(理解)

【スレッド処理の違い】

  • スレッドは共有メモリ空間です。

  • プロセスはメモリに依存しません。

同じプロセス内のスレッドは相互に直接通信できます。

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()

おすすめ

転載: blog.csdn.net/werdasooooo/article/details/134928735