मेरे पास एक प्रश्न है जो वास्तव में मेरी किसी समस्या से संबंधित नहीं है, बल्कि यह है कि यह समस्या क्यों नहीं है। शायद थोड़ा गूंगा है, लेकिन मैं कक्षाओं से सुपर परिचित नहीं हूं और मैं सीखने की कोशिश कर रहा हूं। मान लें कि मेरे पास निम्नानुसार परिभाषित एक वर्ग है:

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)

तो मैं विभिन्न प्रक्रियाओं के बीच समानांतर में, बी के विभिन्न मूल्यों के लिए योग के परिणाम की गणना करना चाहता हूं:

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

pool = mp.Pool(processes=2)
b = [0, 1, 2, 3]
out = pool.map(Calc, b)
print(out)

जो प्रिंट करता है (एक मामले में यह यादृच्छिक है):

[(8, 8), (5, 4), (3, 1), (7, 4)]

क्या सही है। मेरा सवाल यह है कि विभिन्न प्रक्रियाएं एक ही समय में एक वर्ग विशेषता को कैसे संशोधित कर सकती हैं, एक ही समय में (इस उदाहरण में ऑपरेशन काफी तेज है, लेकिन मेरे वास्तविक दुनिया के उदाहरण में ऑपरेशन में कई सेकंड लगते हैं यदि मिनट नहीं हैं, इसलिए समानांतरकरण ) एक दूसरे को प्रभावित किए बिना?

0
mmonti 30 अक्टूबर 2020, 18:06

2 जवाब

सबसे बढ़िया उत्तर

प्रत्येक प्रक्रिया स्वयं निहित है और उनके बीच कोई संचार नहीं है। जब आप फू ऑब्जेक्ट को विभिन्न प्रक्रियाओं में भेजते हैं तो वे अब एक ही चीज़ नहीं होते हैं - उनमें से कई वहां अपनी चीज कर रहे हैं। आपका प्रश्न वास्तव में कक्षाओं या कक्षा के उदाहरणों के बारे में नहीं है बल्कि विभिन्न प्रक्रियाओं में क्या होता है।

इंस्टेंस की आईडी को उसकी a विशेषता के साथ प्रिंट करना स्पष्ट कर सकता है।

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()

...

PS C:\pyprojects> py -m tmp
original foo id:2466513417648
pid:10460 b:1 I am 2729330535728, a: before=1 | after=2 (3, 2)
pid:10460 b:3 I am 2729330535728, a: before=2 | after=5 (8, 5)
pid:10460 b:6 I am 2729330535728, a: before=5 | after=2 (8, 2)
pid:10460 b:8 I am 2729330535728, a: before=2 | after=2 (10, 2)
pid:13100 b:0 I am 2799588470064, a: before=1 | after=1 (1, 1)
pid:13100 b:2 I am 2799588470064, a: before=1 | after=6 (8, 6)
pid:13100 b:5 I am 2799588470064, a: before=6 | after=8 (13, 8)
pid:13100 b:7 I am 2799588470064, a: before=8 | after=0 (7, 0)
2466513417648.a is still 1
PS C:\pyprojects>
2
wwii 30 अक्टूबर 2020, 19:25

प्रत्येक प्रक्रिया अपनी स्मृति के साथ काम करती है, इसलिए वे किसी अन्य प्रक्रिया की वर्ग विशेषता को संशोधित नहीं कर सकते हैं। दूसरी तरफ यदि आप धागे के साथ ऐसा ही करेंगे - आपको दौड़ की स्थिति में समस्याएं मिलेंगी।

0
Sergey Tsaplin 30 अक्टूबर 2020, 18:37