Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有类实例的Python多进程_Python_Python Multiprocessing - Fatal编程技术网

带有类实例的Python多进程

带有类实例的Python多进程,python,python-multiprocessing,Python,Python Multiprocessing,我有一个问题与我的问题无关,而是为什么它不是一个问题。也许有点傻,但我对课程不是很熟悉,我正在努力学习。 假设我有一个定义如下的类: import numpy as np import multiprocessing as mp class Foo(object): def __init__(self, a): self.a = a def Sum(self, b): self.a = np.random.randint(10)

我有一个问题与我的问题无关,而是为什么它不是一个问题。也许有点傻,但我对课程不是很熟悉,我正在努力学习。 假设我有一个定义如下的类:

import numpy as np
import multiprocessing as mp


class Foo(object):
    def __init__(self, a):
        self.a = a

    def Sum(self, b):
        self.a = np.random.randint(10)
        return self.a + b, self.a
我创建了一个对象:

foo = Foo(1)
然后,我想计算不同过程中不同b值的和的结果:

def Calc(b):
    return foo.Sum(b)

pool = mp.Pool(processes=2)
b = [0, 1, 2, 3]
out = pool.map(Calc, b)
print(out)
哪种打印(在一种情况下是随机的):

这是正确的。
我的问题是,不同的进程如何在不影响彼此的情况下同时修改类属性a(在本例中,操作相当快,但在我的现实世界示例中,操作需要几秒钟,如果不是几分钟的话,因此需要并行化)?

每个进程都使用自己的内存,因此,它们不能修改另一个进程的class属性。另一方面,如果你对线程也这么做,你会遇到竞争条件的问题。

每个进程都使用自己的内存,因此它们不能修改另一个进程的class属性。另一方面,如果你对线程也这么做,你会遇到竞争条件的问题。

每个进程都是独立的,它们之间没有通信。当您将foo对象发送到不同的进程时,它们不再是同一件事——它们中的许多人都在做自己的事情。您的问题实际上不是关于类或类实例,而是关于不同进程中发生的事情

打印实例的id及其
属性可以说明这一点

import multiprocessing as mp
import numpy as np

class Foo(object):
    def __init__(self, a):
        self.a = a
    def Sum(self, b):
        s = f'I am {id(self)}, a before={self.a}'
        self.a = np.random.randint(10)
        print(f'{s} | a after={self.a}')
        return self.a + b, self.a

foo = Foo(1)

def Calc(b):
    return foo.Sum(b)

if __name__ == '__main__':

    print(f'original foo id:{id(foo)}')

    pool = mp.Pool(processes=2)
    b = [0, 1, 2, 3, 5, 6, 7, 8]
    out = pool.map(Calc, b)
    print(out)
    print(f'{id(foo)}.a is still {foo.a}') 
    # not sure why this is necessary
    pool.terminate()
然后从命令提示符运行:

PS C:\pyprojects> py -m tmp
original foo id:2235026702928
I am 1850261105632, a before=1 | a after=4
I am 1905926138848, a before=1 | a after=1
I am 1850261105632, a before=4 | a after=8
I am 1905926138848, a before=1 | a after=9
I am 1850261105632, a before=8 | a after=2
I am 1905926138848, a before=9 | a after=9
I am 1850261105632, a before=2 | a after=7
I am 1905926138848, a before=9 | a after=3
[(4, 4), (2, 1), (10, 8), (12, 9), (7, 2), (15, 9), (14, 7), (11, 3)]
2235026702928.a is still 1

播放打印字符串:

import multiprocessing as mp
import numpy as np
import os

class Foo(object):
    def __init__(self, a):
        self.a = a
    def Sum(self, b):
        s = f'I am {id(self)}, a: before={self.a}'
        self.a = np.random.randint(10)
        s = f'{s} | after={self.a}'
        return os.getpid(),s,(self.a + b, self.a),b

foo = Foo(1)

def Calc(b):
    return foo.Sum(b)

if __name__ == '__main__':

    print(f'original foo id:{id(foo)}')

    pool = mp.Pool(processes=2)
    b = [0, 1, 2, 3, 5, 6, 7, 8]
    out = pool.map(Calc, b)
    out.sort(key=lambda x: (x[0],x[-1]))
    for result in out:
        print(f'pid:{result[0]} b:{result[-1]} {result[1]} {result[2]}')
    print(f'{id(foo)}.a is still {foo.a}')
    pool.terminate()


每个过程都是独立的,它们之间没有通信。当您将foo对象发送到不同的进程时,它们不再是同一件事——它们中的许多人都在做自己的事情。您的问题实际上不是关于类或类实例,而是关于不同进程中发生的事情

打印实例的id及其
属性可以说明这一点

import multiprocessing as mp
import numpy as np

class Foo(object):
    def __init__(self, a):
        self.a = a
    def Sum(self, b):
        s = f'I am {id(self)}, a before={self.a}'
        self.a = np.random.randint(10)
        print(f'{s} | a after={self.a}')
        return self.a + b, self.a

foo = Foo(1)

def Calc(b):
    return foo.Sum(b)

if __name__ == '__main__':

    print(f'original foo id:{id(foo)}')

    pool = mp.Pool(processes=2)
    b = [0, 1, 2, 3, 5, 6, 7, 8]
    out = pool.map(Calc, b)
    print(out)
    print(f'{id(foo)}.a is still {foo.a}') 
    # not sure why this is necessary
    pool.terminate()
然后从命令提示符运行:

PS C:\pyprojects> py -m tmp
original foo id:2235026702928
I am 1850261105632, a before=1 | a after=4
I am 1905926138848, a before=1 | a after=1
I am 1850261105632, a before=4 | a after=8
I am 1905926138848, a before=1 | a after=9
I am 1850261105632, a before=8 | a after=2
I am 1905926138848, a before=9 | a after=9
I am 1850261105632, a before=2 | a after=7
I am 1905926138848, a before=9 | a after=3
[(4, 4), (2, 1), (10, 8), (12, 9), (7, 2), (15, 9), (14, 7), (11, 3)]
2235026702928.a is still 1

播放打印字符串:

import multiprocessing as mp
import numpy as np
import os

class Foo(object):
    def __init__(self, a):
        self.a = a
    def Sum(self, b):
        s = f'I am {id(self)}, a: before={self.a}'
        self.a = np.random.randint(10)
        s = f'{s} | after={self.a}'
        return os.getpid(),s,(self.a + b, self.a),b

foo = Foo(1)

def Calc(b):
    return foo.Sum(b)

if __name__ == '__main__':

    print(f'original foo id:{id(foo)}')

    pool = mp.Pool(processes=2)
    b = [0, 1, 2, 3, 5, 6, 7, 8]
    out = pool.map(Calc, b)
    out.sort(key=lambda x: (x[0],x[-1]))
    for result in out:
        print(f'pid:{result[0]} b:{result[-1]} {result[1]} {result[2]}')
    print(f'{id(foo)}.a is still {foo.a}')
    pool.terminate()


是否分配了多个进程来计算同一个Foo实例,或者每个进程都有自己的进程?另外,您可能只是有一个计时窗口没有在本地计算机上命中的竞赛条件。
pool.map(Calc,b)
-什么是
Calc
?您是对的,对不起,我忘了复制Calc,没有定义。他们使用的是相同的实例,或者我假设是这样。当然,我可以在
Calc
中重新实例化对象,但我想知道这是否是一个问题,因为我的原始问题是有效的,并行化肯定会更快。每个进程都是自包含的,它们之间没有通信。当您将foo对象发送到不同的进程时,它们不再是同一件事——它们中的许多人都在做自己的事情。如果在末尾添加
print(foo.a)
,您将看到主进程的foo没有受到影响。你的问题不是关于类或类实例,而是关于不同进程中发生的事情。是否有多个进程分配给计算同一个Foo实例,或者每个进程都有自己的进程?另外,您可能只是有一个计时窗口没有在本地计算机上命中的竞赛条件。
pool.map(Calc,b)
-什么是
Calc
?您是对的,对不起,我忘了复制Calc,没有定义。他们使用的是相同的实例,或者我假设是这样。当然,我可以在
Calc
中重新实例化对象,但我想知道这是否是一个问题,因为我的原始问题是有效的,并行化肯定会更快。每个进程都是自包含的,它们之间没有通信。当您将foo对象发送到不同的进程时,它们不再是同一件事——它们中的许多人都在做自己的事情。如果在末尾添加
print(foo.a)
,您将看到主进程的foo没有受到影响。您的问题实际上不是关于类或类实例,而是关于不同进程中发生的事情。