در برنامهنویسی multiprocessing، ارتباط و تبادل داده بین پردازشها امری ضروری است. در پایتون، برای این کار از چندین روش استفاده میشود که هر کدام ویژگیها و محدودیتهای خاص خود را دارند. در ادامه به بررسی انواع ارتباط Processها در پایتون با مثالهای عملی میپردازیم و در نهایت با یک جدول مقایسهای این روشها را خلاصه میکنیم.
استفاده از Queue (صف)
Queue یکی از روشهای پرکاربرد برای ارتباط بین پردازشها در پایتون است. Queue از ماژول multiprocessing استفاده میکند و به صورت thread-safe عمل میکند. این به این معنی است که میتوان از آن برای ارسال و دریافت دادهها بین پردازشها استفاده کرد بدون اینکه نیاز به نگرانی درباره همگامسازی دستی داشته باشید.
مثال:
from multiprocessing import Process, Queue
def producer(queue):
for i in range(5):
queue.put(i)
queue.put(None) # نشان دهنده اتمام تولید دادهها است
def consumer(queue):
while True:
item = queue.get()
if item is None:
break
print(f"Consumed: {item}")
if __name__ == "__main__":
queue = Queue()
producer_process = Process(target=producer, args=(queue,))
consumer_process = Process(target=consumer, args=(queue,))
producer_process.start()
consumer_process.start()
producer_process.join()
consumer_process.join()استفاده از Pipe (لوله)
Pipe یک کانال دوطرفه بین دو پردازش است که به صورت دیفالت غیر-blocking عمل میکند. این به این معنی است که هر دو پردازش میتوانند به طور همزمان دادهها را بفرستند و بگیرند، اما نیاز به همگامسازی دقیقتر و مدیریت دستی برای اجتناب از deadlock دارد.
from multiprocessing import Process, Pipe
def sender(conn):
for i in range(5):
conn.send(i)
print(f"send: {i}")
conn.close()
def receiver(conn):
while conn.poll():
item = conn.recv()3. استفاده از متغیرهای به اشتراک گذاشته شده
print(f"Received: {item}")
conn.close()
if __name__ == "__main__":
sender_conn, receiver_conn = Pipe()
sender_process = Process(target=sender, args=(sender_conn,))
receiver_process = Process(target=receiver, args=(receiver_conn,))
sender_process.start()
receiver_process.start()
sender_process.join()
receiver_process.join()استفاده از متغیرهای به اشتراک گذاشته شده
متغیرهای به اشتراک گذاشته شده از طریق متغیر های به اشتراک گذاشته شده (مانند Value و Array) در multiprocessing قابل دسترسی است. این امکان را فراهم میکند که چندین پردازش به صورت همزمان به دادههای یکسانی دسترسی داشته باشند و تغییرات را ببینند.
from multiprocessing import Process, Array, Value
import time
def square_numbers(numbers, result, square_value):
for i in range(len(numbers)):
result[i] = numbers[i] ** 2
square_value.value = numbers[0] ** 2 # مقدار مشترک از نوع Value را تنظیم میکنیم
if __name__ == "__main__":
# تعریف یک آرایه مشترک
shared_array = Array('i', range(5))
# تعریف یک مقدار مشترک
shared_value = Value('i', 0)
numbers = [1, 2, 3, 4, 5]
# ایجاد پردازش
process = Process(target=square_numbers, args=(numbers, shared_array, shared_value))
# شروع پردازش
process.start()
# منتظر بمانید تا پردازش به پایان برسد
process.join()
# چاپ آرایه مشترک
print("Shared Array:", list(shared_array))
# چاپ مقدار مشترک
print("Shared Value:", shared_value.value)