web-dev-qa-db-ja.com

Pythonプールマップでのリスト/複数の引数の使用

リストをパラメーターとしてpool.map(co_refresh, input_list)に渡そうとしています。しかしながら、 pool.mapは関数をトリガーしませんでしたco_refresh。また、エラーも返されませんでした。プロセスがハングしているように見えます。

元のコード:

from multiprocessing import Pool
import pandas as pd
import os

account='xxx'
password='xxx'
threads=5
co_links='file.csv'

input_list=[]

pool = Pool(processes=threads)
def co_refresh(url, account, password, outputfile):

    print(url + ' : ' + account + ' : ' + password + ' : ' + outputfile)

    return;

link_pool = pd.read_csv(co_links, skipinitialspace = True)

for i, row in link_pool.iterrows():

    ln = (row.URL, account, password, os.path.join('e:/', row.File_Name.split('.')[0] + '.csv'))

    input_list.append(ln)

pool.map(co_refresh, input_list)

pool.close()

ただし、関数co_refresh。関数に渡すパラメーターとしてリストを使用するにはどうすればよいですか?

旧質問(簡体字):

Input_listの下には、listlistがあります。

[a1, b1, c1, d1]
[a2, b2, c2, d2]
[a3, b3, c3, d3]

私は次のような機能を持っています:

def func(a, b, c, d)
   ###
    return;

この関数にマルチプロセスを使用したいfunc

from multiprocessing import Pool
pool = Pool(processes=5)
pool.map(func, input_list)
pool.close()

ただし、関数funcはトリガーされませんでした。関数に渡すパラメーターとしてリストを使用するにはどうすればよいですか?

8
lovechillcool

作業関数beforeを定義する必要があります。Poolを宣言するとき、その時点からPoolを宣言するとき、 サブワーカープロセスはfork を、ワーカープロセスはその行を超えてコードを実行しないでください。したがって、作業関数が表示されません。

また、pool.map with pool.starmap入力に合わせて。

簡単な例:

from multiprocessing import Pool

def co_refresh(a, b, c, d):
    print(a, b, c, d)

input_list = [f'a{i} b{i} c{i} d{i}'.split() for i in range(4)]
# [['a0', 'b0', 'c0', 'd0'], ['a1', 'b1', 'c1', 'd1'], ['a2', 'b2', 'c2', 'd2'], ['a3', 'b3', 'c3', 'd3']]

pool = Pool(processes=3)
pool.starmap(co_refresh, input_list)
pool.close()
11
georgexsh

以下のコードを検討してください

from multiprocessing.pool import Pool

data = [["a1", "b1", "c1", "d1"],
        ["a2", "b2", "c2", "d2"],
        ["a3", "b3", "c3", "d3"], ]


def someaction(a, b=1, c=2, d=3):
    print(a, b, c, d)

プールを使用してスクリプトでこれを呼び出すとき

pool = Pool(4)
pool.map(someaction, data)

出力は

['a1', 'b1', 'c1', 'd1'] 1 2 3
['a2', 'b2', 'c2', 'd2'] 1 2 3
['a3', 'b3', 'c3', 'd3'] 1 2 3

したがって、aは配列を取得し、残りのすべてのパラメーターは渡されません。 Pool.mapは、関数が引数を1つだけ持つことを想定しています。ケースを機能させるには、ラッパー関数を作成する必要があります

def someaction_wrapper(data):
    someaction(*data)

そして、このラッパー関数をプールで呼び出します。今、あなたは使う

pool = Pool(4)
pool.map(someaction_wrapper, data)

そして、出力は

a1 b1 c1 d1
a2 b2 c2 d2
a3 b3 c3 d3

あなたが望んでいたものはどれですか

1
Tarun Lalwani

georgexshの答えはPython 3で完全に機能します。重要なのは、starmapが複数の引数を関数に渡すことができるということです。

ただし、Python 2を使用する場合、質問 here の下にあるAhmedのコメントで言及されているpythonクラシックアンパックを使用する必要があります。

私の場合、関数の最初に引数を「登録」する必要があります。

def func(args)
   (a, b, c, d) = args
   # You can then use a, b, c, d in your function
    return;
0
lovechillcool