กระบวนการสื่อสาร

การสื่อสารระหว่างกระบวนการหมายถึงการแลกเปลี่ยนข้อมูลระหว่างกระบวนการ จำเป็นต้องแลกเปลี่ยนข้อมูลระหว่างกระบวนการสำหรับการพัฒนาแอปพลิเคชันแบบขนาน แผนภาพต่อไปนี้แสดงกลไกการสื่อสารต่างๆสำหรับการซิงโครไนซ์ระหว่างกระบวนการย่อยต่างๆ -

กลไกการสื่อสารต่างๆ

ในส่วนนี้เราจะเรียนรู้เกี่ยวกับกลไกการสื่อสารต่างๆ กลไกต่างๆอธิบายไว้ด้านล่าง -

คิว

คิวสามารถใช้ได้กับโปรแกรมแบบหลายกระบวนการ คลาสคิวของmultiprocessing โมดูลคล้ายกับไฟล์ Queue.Queueชั้นเรียน ดังนั้นสามารถใช้ API เดียวกันได้Multiprocessing.Queue จัดเตรียมเธรดและประมวลผลกลไก FIFO (เข้าก่อนออกก่อน) ที่ปลอดภัยในการสื่อสารระหว่างกระบวนการต่างๆ

ตัวอย่าง

ต่อไปนี้เป็นตัวอย่างง่ายๆที่นำมาจากเอกสารอย่างเป็นทางการของ python เกี่ยวกับการประมวลผลหลายกระบวนการเพื่อทำความเข้าใจแนวคิดของคลาส Queue ของการประมวลผลหลายขั้นตอน

from multiprocessing import Process, Queue
import queue
import random
def f(q):
   q.put([42, None, 'hello'])
def main():
   q = Queue()
   p = Process(target = f, args = (q,))
   p.start()
   print (q.get())
if __name__ == '__main__':
   main()

เอาต์พุต

[42, None, 'hello']

ท่อ

เป็นโครงสร้างข้อมูลซึ่งใช้ในการสื่อสารระหว่างกระบวนการในโปรแกรมหลายกระบวนการ ฟังก์ชัน Pipe () ส่งคืนคู่ของวัตถุเชื่อมต่อที่เชื่อมต่อกันโดยไปป์ซึ่งโดยค่าเริ่มต้นคือ duplex (สองทาง) มันทำงานในลักษณะต่อไปนี้ -

  • ส่งคืนคู่ของวัตถุการเชื่อมต่อที่แสดงถึงปลายทั้งสองของท่อ

  • ทุกวัตถุมีสองวิธี - send() และ recv()เพื่อสื่อสารระหว่างกระบวนการ

ตัวอย่าง

ต่อไปนี้เป็นตัวอย่างง่ายๆที่นำมาจากเอกสารอย่างเป็นทางการของ python เกี่ยวกับการประมวลผลหลายขั้นตอนเพื่อทำความเข้าใจแนวคิดของ Pipe() หน้าที่ของการประมวลผลหลายขั้นตอน

from multiprocessing import Process, Pipe

def f(conn):
   conn.send([42, None, 'hello'])
   conn.close()

if __name__ == '__main__':
   parent_conn, child_conn = Pipe()
   p = Process(target = f, args = (child_conn,))
   p.start()
   print (parent_conn.recv())
   p.join()

เอาต์พุต

[42, None, 'hello']

ผู้จัดการ

Manager เป็นคลาสของโมดูลการประมวลผลหลายขั้นตอนที่ให้วิธีการประสานข้อมูลที่แชร์ระหว่างผู้ใช้ทั้งหมด อ็อบเจ็กต์ตัวจัดการควบคุมกระบวนการเซิร์ฟเวอร์ซึ่งจัดการอ็อบเจ็กต์ที่แบ่งใช้และอนุญาตให้โปรเซสอื่นจัดการอ็อบเจ็กต์เหล่านั้น กล่าวอีกนัยหนึ่งผู้จัดการมีวิธีสร้างข้อมูลที่สามารถใช้ร่วมกันระหว่างกระบวนการต่างๆ ต่อไปนี้เป็นคุณสมบัติที่แตกต่างกันของวัตถุผู้จัดการ -

  • คุณสมบัติหลักของผู้จัดการคือการควบคุมกระบวนการเซิร์ฟเวอร์ซึ่งจัดการอ็อบเจ็กต์ที่แบ่งใช้

  • คุณสมบัติที่สำคัญอีกประการหนึ่งคือการอัพเดตอ็อบเจ็กต์ที่แบ่งใช้ทั้งหมดเมื่อกระบวนการใด ๆ แก้ไข

ตัวอย่าง

ต่อไปนี้เป็นตัวอย่างที่ใช้อ็อบเจ็กต์ตัวจัดการสำหรับสร้างเรกคอร์ดรายการในกระบวนการเซิร์ฟเวอร์จากนั้นเพิ่มเร็กคอร์ดใหม่ในรายการนั้น

import multiprocessing

def print_records(records):
   for record in records:
      print("Name: {0}\nScore: {1}\n".format(record[0], record[1]))

def insert_record(record, records):
   records.append(record)
      print("A New record is added\n")

if __name__ == '__main__':
   with multiprocessing.Manager() as manager:

      records = manager.list([('Computers', 1), ('Histoty', 5), ('Hindi',9)])
      new_record = ('English', 3)

      p1 = multiprocessing.Process(target = insert_record, args = (new_record, records))
      p2 = multiprocessing.Process(target = print_records, args = (records,))
	  p1.start()
      p1.join()
      p2.start()
      p2.join()

เอาต์พุต

A New record is added

Name: Computers
Score: 1

Name: Histoty
Score: 5

Name: Hindi
Score: 9

Name: English
Score: 3

แนวคิดของ Namespaces ใน Manager

คลาสผู้จัดการมาพร้อมกับแนวคิดของเนมสเปซซึ่งเป็นวิธีการที่รวดเร็วในการแบ่งปันแอตทริบิวต์ต่างๆในหลายกระบวนการ เนมสเปซไม่มีคุณลักษณะสาธารณะใด ๆ ซึ่งสามารถเรียกใช้ได้ แต่มีแอตทริบิวต์ที่เขียนได้

ตัวอย่าง

ตัวอย่างสคริปต์ Python ต่อไปนี้ช่วยให้เราใช้เนมสเปซสำหรับการแชร์ข้อมูลระหว่างกระบวนการหลักและกระบวนการย่อย -

import multiprocessing

def Mng_NaSp(using_ns):

   using_ns.x +=5
   using_ns.y *= 10

if __name__ == '__main__':
   manager = multiprocessing.Manager()
   using_ns = manager.Namespace()
   using_ns.x = 1
   using_ns.y = 1

   print ('before', using_ns)
   p = multiprocessing.Process(target = Mng_NaSp, args = (using_ns,))
   p.start()
   p.join()
   print ('after', using_ns)

เอาต์พุต

before Namespace(x = 1, y = 1)
after Namespace(x = 6, y = 10)

Ctypes-Array และ Value

Multiprocessing module จัดเตรียมอ็อบเจ็กต์ Array และ Value สำหรับจัดเก็บข้อมูลในแผนที่หน่วยความจำแบบแบ่งใช้ Array เป็นอาร์เรย์ ctypes ที่จัดสรรจากหน่วยความจำแบบแบ่งใช้และ Value เป็นวัตถุ ctypes ที่จัดสรรจากหน่วยความจำแบบแบ่งใช้

ในการใช้งานให้นำเข้ากระบวนการค่าอาร์เรย์จากการประมวลผลหลายกระบวนการ

ตัวอย่าง

สคริปต์ Python ต่อไปนี้เป็นตัวอย่างที่นำมาจากเอกสาร python เพื่อใช้ประโยชน์จาก Ctypes Array และ Value สำหรับการแบ่งปันข้อมูลระหว่างกระบวนการ

def f(n, a):
   n.value = 3.1415927
   for i in range(len(a)):
   a[i] = -a[i]

if __name__ == '__main__':
   num = Value('d', 0.0)
   arr = Array('i', range(10))

   p = Process(target = f, args = (num, arr))
   p.start()
   p.join()
   print (num.value)
   print (arr[:])

เอาต์พุต

3.1415927
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]

การสื่อสารกระบวนการตามลำดับ (CSP)

CSP ใช้เพื่อแสดงการทำงานร่วมกันของระบบกับระบบอื่น ๆ ที่มีโมเดลพร้อมกัน CSP เป็นกรอบสำหรับการเขียนพร้อมกันหรือโปรแกรมผ่านการส่งข้อความและด้วยเหตุนี้จึงมีประสิทธิภาพสำหรับการอธิบายการทำงานพร้อมกัน

ไลบรารี Python - PyCSP

สำหรับการใช้งาน Core Primitives ที่พบใน CSP Python มีไลบรารีที่เรียกว่า PyCSP ช่วยให้การใช้งานสั้นและอ่านง่ายเพื่อให้สามารถเข้าใจได้ง่ายมาก ต่อไปนี้เป็นเครือข่ายกระบวนการพื้นฐานของ PyCSP -

ในเครือข่ายกระบวนการ PyCSP ข้างต้นมีสองกระบวนการ - กระบวนการ 1 และกระบวนการ 2 กระบวนการเหล่านี้สื่อสารโดยส่งข้อความผ่านสองช่องทาง - ช่องทาง 1 และช่องทาง 2

การติดตั้ง PyCSP

ด้วยความช่วยเหลือของคำสั่งต่อไปนี้เราสามารถติดตั้ง Python library PyCSP -

pip install PyCSP

ตัวอย่าง

การทำตามสคริปต์ Python เป็นตัวอย่างง่ายๆสำหรับการรันสองกระบวนการควบคู่กัน ทำได้ด้วยความช่วยเหลือของ PyCSP python libabary -

from pycsp.parallel import *
import time
@process
def P1():
   time.sleep(1)
   print('P1 exiting')
@process
def P2():
   time.sleep(1)
   print('P2 exiting')
def main():
   Parallel(P1(), P2())
   print('Terminating')
if __name__ == '__main__':
   main()

ในสคริปต์ข้างต้นมีสองฟังก์ชันคือ P1 และ P2 ถูกสร้างขึ้นแล้วตกแต่งด้วย @process สำหรับการแปลงเป็นกระบวนการ

เอาต์พุต

P2 exiting
P1 exiting
Terminating