Pythonマルチスレッドスレッドプールのマップとスターマップの比較

Pythonマルチスレッドスレッドプールのマップとスターマップの比較

マップとスターマップはどちらもマルチスレッドで同期実行する方法です。この 2 つの違いは、マップ関数を使用してスレッド プールに配置されたタスクはパラメータを 1 つだけ受け入れることができるのに対し、スターマップ関数を使用してスレッド プールに配置されたタスクはパラメータを 1 つだけ受け入れることができることです。複数のパラメータを受け入れます。この観点から見ると、実は、map 関数よりも starmap 関数の方が便利です。

以下はケース分析です (各コードセグメント内のジョブ関数のパラメーターの数と、マップまたはスターマップが使用されているかどうかに注意してください)。

マップ関数を使用すると、タスクは 1 つのパラメータのみを受け取ります

import multiprocessing as mp
import numpy as np

def job(x): # 在此案例中,目标函数(即后面提到的“任务”)就是job函数,后面会将job函数放入进程池
  return x * x
  
def multicore():
  # 创建进程池
  # pool = mp.Pool() # 默认使用所有CPU核
  pool = mp.Pool(processes = 2) # 使用processes指定使用的CPU核的数量
    
  args = np.arange(10) # 创建10次任务的参数
  res = pool.map(job, args) # map可以一次接收多次任务的参数,但是每次任务只能接收1个参数
  print(res) # 输出结果长度为10,对应10次任务的运行结果

if __name__ == "__main__":
    multicore()

マップ関数を使用すると、タスクは複数のパラメータを受け入れます

import multiprocessing as mp
import numpy as np

# 在此案例中,目标函数(即后面提到的“任务”)就是job函数,后面会将job函数放入进程池
def job(x, y): # 与前一个案例相比,job函数有所修改:在此案例中job函数接收2个参数
  return x * y
  
def multicore():
  # 创建进程池
  # pool = mp.Pool() # 默认使用所有CPU核
  pool = mp.Pool(processes = 2) # 使用processes指定使用的CPU核的数量
    
  args = [(1, 2), (3, 4), (5, 6)] # 创建3次任务的参数,每次任务接收2个参数
  res = pool.map(job, args) # map可以一次接收多次任务的参数,每次任务只能接收1个参数。但是args中每次任务都给了2个参数,所以这个案例会报错
  print(res) # 报错,无法输出结果

if __name__ == "__main__":
    multicore()

マップ関数を使用してタスクをプロセス プールに配置する場合、タスクは 1 つのパラメーターしか受け取ることができないため、上記の場合はエラーが報告されます。では、どのように変更すればよいのでしょうか? ここでは 2 種類の改造計画を示します。

変更 1: 代わりにスターマップ関数を使用する

import multiprocessing as mp

def job(x, y): # 用starmap函数将任务放进进程池时,任务可以接收一个及以上的参数
  return x * y

def multicore():
  # pool = mp.Pool() # 默认使用所有CPU核
  pool = mp.Pool(processes = 2) # 使用processes指定使用的CPU核的数量
    
  args = [(1, 2), (3, 4)]
  res = pool.starmap(job, args) # starmap也可以一次接收多次任务的参数,并且每次任务的参数可以不止1个
  print(res)

multicore()

変更計画 2: タスクを変更し、タスク内のパラメーターを「解凍」します。

import multiprocessing as mp

def job(args): # 用map函数将任务放进进程池时,任务只能接收一个参数
  x, y = args # 这个例子就是job函数的运行本来需要接收2个参数,但是用map函数将job任务放进进程池,那就只能先将2个参数放进一个元组里形成1个参数,然后在job函数里再将2个参数分开来
  return x * y

def multicore():
  # pool = mp.Pool() # 默认使用所有CPU核
  pool = mp.Pool(processes = 2) # 使用processes指定使用的CPU核的数量
  
  args = [(1, 2), (3, 4)]
  res = pool.map(job, args) # map可以一次接收多次任务的参数,但是每次任务接收的参数只能是1个。(1, 2)为第一次任务的参数(虽然看起来传了2个参数,但实际上是作为一个元组,所以是只传了1个参数),(3, 4)为第二次任务的参数(一个元组)
  print(res)

if __name__ == "__main__":
    multicore()

このアプローチの制限は、目的関数/タスクを変更できる必要があることです。

変更 3: 部分関数を使用してタスク外の関数を変更する

from functools import partial
import multiprocessing as mp

# 在此案例中,目标函数(即后面提到的“任务”)就是job函数,后面会将job函数放入进程池
def job(x, y): # 在此案例中job函数接收2个参数
  return x * y
  
def multicore():
  # 创建进程池
  # pool = mp.Pool() # 默认使用所有CPU核
  pool = mp.Pool(processes = 2) # 使用processes指定使用的CPU核的数量
  
  job2 = partial(job, y = 2) # 使用partial函数,将job函数的其中一个参数固定取值为2,返回一个新函数,这个函数相当于只需要接收1个参数.新函数的名字不能与原函数的名字相同,否则会报错
  args = [1, 2, 3] # 创建3次任务的参数,这个参数是未被固定取值的参数
  res = pool.map(job2, args)
  print(res) # [2, 4, 6]

if __name__ == "__main__":
    multicore()

部分関数の役割は、関数の特定のパラメーターを修正する (つまり、デフォルト値を設定する) ことで、元の関数と同じ機能を持つ新しい関数が取得されます。この新しい関数を呼び出すには、次の情報を提供するだけです。固定パラメータではないパラメータで十分です。

このメソッドの制限は、タスクの複数のパラメーターの 1 つが固定値である必要があることです。

Partial関数の説明は「Pythonを徹底理解するpartial()」の記事を参照してください。

参考: Python マルチスレッドの使用法_multiprocessing

この記事では、同期実行と非同期実行の違い、およびマップとスターマップの使用について紹介します。ただし、マップとスターマップの違いを紹介するために使用されるケースは十分に明確ではありません。

マルチプロセッシング プール map() 複数の引数

この記事では、複数のパラメーターを使用する必要がある場合に、Python マルチスレッドでプロセス プールの map() 関数を適用する方法を紹介します。この記事では、4 つの解決策を紹介しています: ① apply_async() を使用する; ** ② starmap() を使用する; ** ③ ターゲット関数を変更し、ターゲット関数内のパラメータ グループを「解凍」して複数のパラメータを分離する; ④ ラッパー関数「Unpack」を使用する" パラメータグループ。

この解決策③だけを見ました。

おすすめ

転載: blog.csdn.net/Mocode/article/details/132133603