2014-11-06 5 views
3

파이썬 프로그램의 서로 다른 프로세스간에 공유 객체 (클래스의 인스턴스) 배열을 만들려고합니다. 이러한 각 개체는 프로그램에서 수정됩니다.파이썬에서 멀티 프로세싱을 사용하는 공유 배열

import multiprocessing 
import numpy as np 
sh = multiprocessing.RawArray (ctypes.py_object, 10) 
f = np.frombuffer(sh, dtype=object) 

을하고 내가 오류는 다음과 같습니다 :

Traceback (most recent call last): 
    File "<pyshell#14>", line 1, in <module> 
    f = np.frombuffer(sh, dtype=object) 
ValueError: cannot create an OBJECT array from memory buffer 

이제 내 질문은, 우선이 문제를 해결하기 위해이 일반적으로 올바른 방법입니다 다음과 같이 이러한 목적을 위해 나는 멀티 프로세싱을 사용하고 있습니다 , 둘째, 위의 코드에서 내 실수는 무엇입니까? 미리 감사드립니다.

답변

3

ctypes.py_object은 C에서 PyObject *을 나타냅니다. 이것은 struct에 대한 포인터로, Python 개체를 나타내며 프로세스의 개인 메모리에 상주하며 더 많은 포인터를 포함합니다. 다른 프로세스는이 프로세스에 액세스 할 수 없습니다. 프로세스간에 포인터를 공유하려고하면 유용하지 않습니다.

도 참조하십시오. this answer by Alex Martelli.

+0

실제로 Array 및 RawArray (다중 처리에서)를 사용하면 여러 프로세스에서 액세스 할 수있는 메모리에 공유 배열을 만들 수 있습니다. 위의 코드를 작성하면 정수 배열을 공유 할 수 있지만 객체 배열에 문제가 있습니다. 예를 들어 다음과 같이 쓰면 : >>> 다중 처리를 mp 으로 가져 오기 >>> numpy를 np로 가져 오기 >>> sh = mp.RawArray (ctypes.c_int, 10) >>> f = np.frombuffer (sh, dtype = int) >>> f [0] = 1 >>> sh [0] 그것은 완벽하게 작동합니다! – user823743

+0

@ user823743 맞지만 포인터로도 똑같이 할 수는 없습니다. –

+0

당신은 정확합니다; 다행스럽게도 나는 다중 처리를 피하는 또 다른 방법을 발견했다. 감사. – user823743

0

유형을 걱정하지 않고 객체를 덤프 할 수있는 multiprocessing.Queue을 사용할 수 있습니다. 또한 스레드로부터 안전하고 프로세스 안전합니다.

다음은 생산자 - 소비자 문제를 촉진하는 데 사용되는 대기열의 간단한 예입니다 (original source, 피자는 저에게 약간의 보너스였습니다).

from multiprocessing import Process, Queue 

class Pizza(object): 
    def __init__(self, pizza_num): 
     self.pizza_num = pizza_num 
     self.num_slices = 8 

sentinel = "NO PIZZA" 

def producer(initial_num_pizzas, total_num_pizzas, q): 
    """Cooks Pizzas to be consumed and waits for the consumer to finish eating.""" 
    print("Producer: I am cooking %s Pizzas and putting them on the Queue!"%(total_num_pizzas-initial_num_pizzas)) 
    for i in range(q.qsize(), total_num_pizzas): 
     print("Producer: Behold, for I have cooked Pizza no. %s"%i) 
     q.put(Pizza(i)) 
    q.put(sentinel) 

def consumer(q): 
    """Consumes some Pizza. In this case, all it does is set the number of slices to 0.""" 
    while True: 
     pizza = q.get() 
     pizza.num_slices = 0 
     if pizza == sentinel: 
      break 
     print("Comsumer: Pizza no. %s was found! It has %s slices, yum!"%(pizza.pizza_num, pizza.num_slices)) 

if __name__ == '__main__': 
    q = Queue() 
    total_num_pizzas = 10 
    initial_num_pizzas = 4 
    ## Let's add some Pizzas beforehand: 
    for i in range(0, initial_num_pizzas): 
     q.put(Pizza(i)) 
    print("Main: I have precooked %s Pizzas."%q.qsize()) 

    producer_proc = Process(target=producer, args=(initial_num_pizzas, total_num_pizzas, q)) 
    consumer_proc = Process(target=consumer, args=(q,)) 
    producer_proc.start() 
    consumer_proc.start() 

    q.close() ## Shop is closed, no more Pizzas will be added to Queue! 
    q.join_thread() 

    producer_proc.join() 
    consumer_proc.join() 

다음은 출력 예입니다. 이를 실행하면 병렬 프로세스의 비 결정적 실행으로 인해 Producer 및 Consumer 인쇄 문이 다르게 인터리브 될 수 있습니다.

Main: I have precooked 4 Pizzas. 
Producer: I am cooking 6 Pizzas and putting them on the Queue! 
Producer: Behold, for I have cooked Pizza no. 4 
Producer: Behold, for I have cooked Pizza no. 5 
Producer: Behold, for I have cooked Pizza no. 6 
Producer: Behold, for I have cooked Pizza no. 7 
Comsumer: Pizza no. 0 was found! It has 8 slices, yum! 
Comsumer: Pizza no. 1 was found! It has 8 slices, yum! 
Producer: Behold, for I have cooked Pizza no. 8 
Comsumer: Pizza no. 2 was found! It has 8 slices, yum! 
Producer: Behold, for I have cooked Pizza no. 9 
Comsumer: Pizza no. 3 was found! It has 8 slices, yum! 
Comsumer: Pizza no. 4 was found! It has 8 slices, yum! 
Comsumer: Pizza no. 5 was found! It has 8 slices, yum! 
Comsumer: Pizza no. 6 was found! It has 8 slices, yum! 
Comsumer: Pizza no. 7 was found! It has 8 slices, yum! 
Comsumer: Pizza no. 8 was found! It has 8 slices, yum! 
Comsumer: Pizza no. 9 was found! It has 8 slices, yum! 

use Sentinels to mark the end of your Queue입니다. 나는 여기에 "피자"를 사용했지만 아무 것도 할 수 없습니다.

관련 문제