유형을 걱정하지 않고 객체를 덤프 할 수있는 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입니다. 나는 여기에 "피자"를 사용했지만 아무 것도 할 수 없습니다.
실제로 Array 및 RawArray (다중 처리에서)를 사용하면 여러 프로세스에서 액세스 할 수있는 메모리에 공유 배열을 만들 수 있습니다. 위의 코드를 작성하면 정수 배열을 공유 할 수 있지만 객체 배열에 문제가 있습니다. 예를 들어 다음과 같이 쓰면 : >>> 다중 처리를 mp 으로 가져 오기 >>> numpy를 np로 가져 오기 >>> sh = mp.RawArray (ctypes.c_int, 10) >>> f = np.frombuffer (sh, dtype = int) >>> f [0] = 1 >>> sh [0] 그것은 완벽하게 작동합니다! – user823743
@ user823743 맞지만 포인터로도 똑같이 할 수는 없습니다. –
당신은 정확합니다; 다행스럽게도 나는 다중 처리를 피하는 또 다른 방법을 발견했다. 감사. – user823743