简体   繁体   English

Python 多处理和共享 memory - 为什么我得到不同的结果?

[英]Python multiprocessing and shared memory - why do I get different results?

I'm testing some python code to share a numpy array between 2 processes.我正在测试一些 python 代码以在 2 个进程之间共享 numpy 数组。

from multiprocessing import Process, Semaphore, shared_memory
import numpy as np
import time

def reader(id, a, shm):
    exst_shm = shared_memory.SharedMemory(name=shm)
    b = np.ndarray(a.shape, dtype=a.dtype, buffer=exst_shm.buf)
        
    time.sleep(2)    
    print('FUNCTION VERSION: ', b[0])   
    

def worker(id, a, shm):
    exst_shm = shared_memory.SharedMemory(name=shm)
    b = np.ndarray(a.shape, dtype=a.dtype, buffer=exst_shm.buf) 
    b[0] += 10 


if __name__ == "__main__":
    a = np.array([0])
    shm = shared_memory.SharedMemory(create=True, size=a.nbytes) 
    c = np.ndarray(a.shape, dtype=a.dtype, buffer=shm.buf)
    
    th1 = Process(target=reader, args=(1, a, shm.name))
    th2 = Process(target=worker, args=(2, a, shm.name))
    
    th1.start()
    th2.start()
    th1.join()
    th2.join()

The code above works fine and it prints out: FUNCTION VERSION: 10上面的代码工作正常,它打印出来: FUNCTION VERSION: 10

from multiprocessing import Process, Semaphore, shared_memory
import numpy as np
import time

class Reader(Process):
    def __init__(self, id, a, shm):
        Process.__init__(self)
        
        exst_shm = shared_memory.SharedMemory(name=shm)
        b = np.ndarray(a.shape, dtype=a.dtype, buffer=exst_shm.buf) 
        
        time.sleep(2)    
        print('SUBCLASS VERSION: ', b[0])   
       
class Worker(Process):
    def __init__(self, id, a, shm):
        Process.__init__(self)
            
        exst_shm = shared_memory.SharedMemory(name=shm) 
        b = np.ndarray(a.shape, dtype=a.dtype, buffer=exst_shm.buf) 
        b[0] += 10
        
if __name__ == "__main__":
    a = np.array([0])
    shm = shared_memory.SharedMemory(create=True, size=a.nbytes) 
    c = np.ndarray(a.shape, dtype=a.dtype, buffer=shm.buf)
    
    th1 = Reader(1, a, shm.name)
    th2 = Worker(2, a, shm.name)

    th1.start()
    th2.start()
    th1.join()
    th2.join()

However, when it's written as classes, it prints out: SUBCLASS VERSION: 0. Where does the difference come from and what is wrong with the code?但是,当它写成类时,它会打印出: SUBCLASS VERSION: 0。差异来自哪里,代码有什么问题?

You create classes in wrong way.您以错误的方式创建课程。

Normally start() runs method run() to execute target in new process.通常start()运行方法run()以在新进程中执行target

When you create own class then you have to overwrite method run() and put your code inside run() and then it will run this code when you use start() .当您创建自己的 class 时,您必须覆盖方法run()并将代码放在run() ,然后当您使用start()时它将运行此代码。

In your version it runs all your code in main process, not in new processes.在您的版本中,它在主进程中运行您的所有代码,而不是在新进程中。 First you create Reader() which sleeps 2s and prints result b[0] , and later you create Worker() which adds b[0] += 10 .首先你创建Reader()睡眠 2s 并打印结果b[0] ,然后你创建Worker()添加b[0] += 10 And after that you start() processes - but they have nothing to do because you didn't overwrite run() and you don't have target in classes.之后你start()进程 - 但它们无事可做,因为你没有覆盖run()并且你在类中没有target

from multiprocessing import Process, Semaphore, shared_memory
import numpy as np
import time

class Reader(Process):
    def __init__(self, id, a, shm):
        Process.__init__(self)
        
        self.exst_shm = shared_memory.SharedMemory(name=shm)
        self.b = np.ndarray(a.shape, dtype=a.dtype, buffer=self.exst_shm.buf) 
        
    def run(self):            
        time.sleep(2)
        print('SUBCLASS VERSION: ', self.b[0])   
       
class Worker(Process):
    def __init__(self, id, a, shm):
        Process.__init__(self)
        
        self.exst_shm = shared_memory.SharedMemory(name=shm) 
        self.b = np.ndarray(a.shape, dtype=a.dtype, buffer=self.exst_shm.buf) 

    def run(self):            
        self.b[0] += 10
        
if __name__ == "__main__":
    a = np.array([0])
    shm = shared_memory.SharedMemory(create=True, size=a.nbytes) 
    c = np.ndarray(a.shape, dtype=a.dtype, buffer=shm.buf)
    
    th1 = Reader(1, a, shm.name)
    th2 = Worker(2, a, shm.name)

    th1.start()
    th2.start()
    th1.join()
    th2.join()

BTW:顺便提一句:

Using使用

import multiprocessing
print(multiprocessing.__file__)

you can find source code and see in process.py how it works.您可以在process.py中找到源代码并查看它是如何工作的。

def run(self):
    '''
    Method to be run in sub-process; can be overridden in sub-class
    '''
    if self._target:
        self._target(*self._args, **self._kwargs)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM