如何在多处理函数中传递参数以及如何使用多处理列表?

Posted

技术标签:

【中文标题】如何在多处理函数中传递参数以及如何使用多处理列表?【英文标题】:How to pass argument in multiprocessing function and how to use multiprocessing list? 【发布时间】:2020-09-28 20:03:21 【问题描述】:

我正在尝试在 python 中使用多处理。我创建了一个函数,将值附加到传递给该函数的列表中(check_m_process)。我正在尝试传递一个在外部定义的列表 (m)。由于普通列表变量不会在多处理函数之外自行更新,因此我使用了多处理列表来查看我的函数对列表所做的更改。

在执行函数时,它显示参数错误,如下面的输出所示,而不是传递参数。

import multiprocessing

# common list
m =  multiprocessing.Manager().list()

def check_m_process(m):
    print('m before - ',list(m))
    for i in range(5):
        m = m + [i]
    print('m in function - ',list(m))
    
p1 = multiprocessing.Process(target = check_m_process, args=(m))
p1.start()
p1.join()

输出错误:

处理 Process-37:

Traceback(最近一次调用最后一次):

文件“/usr/lib/python2.7/multiprocessing/process.py”,第 258 行,在 _bootstrap 中

self.run()

文件“/usr/lib/python2.7/multiprocessing/process.py”,第 114 行,运行中

self._target(*self._args, **self._kwargs)

TypeError: check_m_process() 只接受 1 个参数(给定 0)

但是,上面的函数在没有多处理的情况下执行,如check_m_process([])。但是当我添加一些额外的参数时,函数会执行,如下面的输出所示。我对多处理函数中的参数如何工作或它应该如何实际传递感到困惑,例如如何仅通过多处理函数传递单个参数。

def check_m_process(tmp_str,m):
    print('m before - ',list(m))
    for i in range(5):
        m = m + [i]
    print('m in function - ',list(m))

p1 = multiprocessing.Process(target = check_m_process, args=('',m))
p1.start()
p1.join()

输出:

('m before -', [])

('m in function - ', [0, 1, 2, 3, 4])

所以在函数执行后,我希望定义的列表 (m) 现在必须在函数执行后按照上面显示的输出进行更新。

print('m outside function - ',list(m))

输出:

('m 函数外 - ', [])

但是在打印列表m的值后,它显示为空,而不是一开始就将变量定义为多处理列表。

有人可以帮助我如何在多处理函数中传递单个参数以及如何在整个多处理函数中使用公共列表吗?或者有没有其他的处理方法?

【问题讨论】:

【参考方案1】:

对于您的第一个问题,您需要在参数处传递(m,)(注意结尾的逗号)。这是在 Python 中创建单元素元组所需的语法。当您只用括号将单个项目括起来时,不会创建元组。

对于第二个问题,您只需将项目附加到multiprocessing.Manager().list(),而不是重复重新分配变量:

for i in range(5):
    m.append(i)

您当前的做法实际上是创建一个常规 Python 列表,并将 m 分配给该列表,而不是更新您的 multiprocessing 列表

>>> i = multiprocessing.Manager().list()
>>> i
<ListProxy object, typeid 'list' at 0x7fa18483b590>
>>> i = i + ['a']
>>> i
['a']

请注意,在我将i['a'] 连接后,它不再是ListProxy,它只是一个普通的list。使用append 可以避免这种情况:

>>> i = multiprocessing.Manager().list()
>>> i
<ListProxy object, typeid 'list' at 0x7fa18483b6d0>
>>> i.append('a')
>>> i
<ListProxy object, typeid 'list' at 0x7fa18483b6d0>
>>> str(i)
"['a']"

【讨论】:

以上是关于如何在多处理函数中传递参数以及如何使用多处理列表?的主要内容,如果未能解决你的问题,请参考以下文章

在多值参数中选择两个选项但传递一个值

创建函数-----------(在函数中使用变量向函数传递参数在函数中处理变量关键字local)

如何在多片段活动中处理 onContextItemSelected?

如何避免在多线程处理中重写类?

在多处理中更新列表字典

如何将参数(不是命令行参数)传递给批处理脚本中的函数