【问题标题】:Global variable access during Python multiprocessingPython 多处理期间的全局变量访问
【发布时间】:2021-07-14 15:56:38
【问题描述】:

命名两个列表 A、B

我想从 A 列表中删除 B 列表元素。

不使用多处理的 Python 代码

A = ["leo", "kiki", "eden"]
B = ["eden", "kiki"]

for i in B:
    A.remove(i)

我想到的多处理代码如下。

from multiprocessing import Pool
import time
A = ["leo", "kiki", "eden"]
B = ["eden", "kiki"]


def test(i):
    global A
    A.remove(i)
    print("intest : ",A)




if __name__ == '__main__':
    global A
    pool = Pool(processes=2)
    pool.map(test ,B)
    pool.close()
    pool.join()
    print("final : ",A)

输出结果:

intest :  ['leo', 'kiki']
intest :  ['leo']
final :  ['leo', 'kiki', 'eden']

为什么在“intest”中全局变量应用正确。

在“final”中,全局变量更改不适用?

请给我很多帮助。

【问题讨论】:

  • 它们是具有独立内存的独立进程;常规变量不会在进程之间神奇地复制。这种魔法只保留给特殊的multiprocessing 类型,例如队列和shared_memory 块。
  • 考虑到这一点,我们真的需要知道您对multiprocessing 的实际操作。我认为您的问题可能过于简单化了? :)
  • @AKX 谢谢你的回复 :) 我会搜索一些 multiprosessing queues 和 shared_memory!!!

标签: python multiprocessing


【解决方案1】:

全局变量不在进程之间共享。当您创建一个新进程时,它会启动一个不同的 python 实例。他们不能分享价值观,他们只是在创造时被复制。您对子进程所做的任何调整将只对该进程可见,而不是启动它们的原始 python 进程。

要解决这个问题,您可以使用多处理模块中的managers。您可以创建一个manager.list(),它允许在进程之间共享值。以下示例删除了全局参数并使用了Manager 类:

import time
from multiprocessing import Pool
from multiprocessing import Manager


def test(test_list,i):
    test_list.remove(i)
    print("intest : ", test_list)
    

if __name__ == '__main__':
    with Manager() as manager:
        A = manager.list(["leo", "kiki", "eden"])
        B = ["eden", "kiki"]

        print("Start : ", A)
        pool = Pool(processes=2)
        pool.starmap(test, [(A, K) for K in B])
        pool.close()
        pool.join()
        print("Final : ", A)

【讨论】:

  • 我运行了您发布的代码。有一个小错误。(在 test(i) 中处理全局变量 A
  • 所以我稍微编辑了一下,它工作得很好^^这很有帮助!使用管理器 def test(A,i): A.remove(i) print("intest : ", A) if name == 'main': with Manager( ) 作为经理: A = manager.list(["leo", "kiki", "eden"]) B = ["eden", "kiki"] print("Start : ", A) pool = Pool(processes= 2) pool.starmap(test, [(A, K) for K in B]) pool.close() pool.join() print("Final : ", A)
  • 你是对的,我相应地编辑了答案。我一定是错误地复制了我的测试函数,它应该包含一个额外的参数。我还将 pool.map() 调整为 pool.starmap(),在这种情况下确实更正确。谢谢!
【解决方案2】:

多线程时使用global 共享内存就足够了。在多处理上共享内存必须以不同的方式实现,这是因为不同的进程使用变量和对象的不同“副本”。通过使用多处理模块的SharedMemory 类可以在进程之间共享内存,该模块还提供了通过使用ShareableList 类创建可以在进程之间共享的类似列表的对象的能力。所以你应该这样转换你的代码:

from multiprocessing import shared_memory
A = shared_memory.ShareableList(["leo", "kiki", "eden"])
# you must always close and unlink shared_memory
A.shm.close()
A.shm.unlink()    

您可以在官方 python 文档中阅读更多相关信息: https://docs.python.org/3/library/multiprocessing.shared_memory.html

【讨论】:

  • 感谢您的帮助。 Python 版本低。我还没试过,但我会试试的。 ^^
猜你喜欢
  • 2019-01-11
  • 2019-12-12
  • 2023-03-15
  • 1970-01-01
  • 2012-06-28
  • 1970-01-01
  • 2018-06-17
  • 1970-01-01
  • 2021-07-22
相关资源
最近更新 更多