Procesy komunikacji wewnętrznej

Komunikacja między procesami oznacza wymianę danych między procesami. Konieczna jest wymiana danych między procesami w celu stworzenia równoległej aplikacji. Poniższy diagram przedstawia różne mechanizmy komunikacji do synchronizacji między wieloma procesami podrzędnymi -

Różne mechanizmy komunikacji

W tej sekcji poznamy różne mechanizmy komunikacji. Mechanizmy opisano poniżej -

Kolejki

Kolejki mogą być używane w programach wieloprocesowych. Klasa Queuemultiprocessing moduł jest podobny do Queue.Queueklasa. W związku z tym można użyć tego samego interfejsu API.Multiprocessing.Queue zapewnia nam bezpieczny wątkowo i procesowy mechanizm komunikacji między procesami FIFO (first-in-first-out).

Przykład

Poniżej znajduje się prosty przykład zaczerpnięty z oficjalnych dokumentów Pythona na temat przetwarzania wieloprocesowego, aby zrozumieć koncepcję klasy Queue przetwarzania wieloprocesowego.

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()

Wynik

[42, None, 'hello']

Rury

Jest to struktura danych, która służy do komunikacji między procesami w programach wieloprocesowych. Funkcja Pipe () zwraca parę obiektów połączeniowych połączonych potokiem, który domyślnie jest dupleksowy (dwukierunkowy). Działa w następujący sposób -

  • Zwraca parę obiektów połączeniowych, które reprezentują dwa końce rury.

  • Każdy obiekt ma dwie metody - send() i recv()do komunikacji między procesami.

Przykład

Poniżej znajduje się prosty przykład zaczerpnięty z oficjalnych dokumentów Pythona na temat przetwarzania wieloprocesowego, aby zrozumieć koncepcję Pipe() funkcja wieloprocesowości.

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()

Wynik

[42, None, 'hello']

Menedżer

Manager to klasa modułu wieloprocesorowego, która zapewnia sposób koordynowania wymiany informacji między wszystkimi jego użytkownikami. Obiekt menedżera steruje procesem serwera, który zarządza obiektami współużytkowanymi i umożliwia innym procesom manipulowanie nimi. Innymi słowy, menedżerowie zapewniają sposób tworzenia danych, które można udostępniać między różnymi procesami. Poniżej przedstawiono różne właściwości obiektu menedżera -

  • Główną właściwością menedżera jest sterowanie procesem serwera, który zarządza współdzielonymi obiektami.

  • Inną ważną właściwością jest aktualizowanie wszystkich współdzielonych obiektów, gdy modyfikuje je dowolny proces.

Przykład

Poniższy przykład wykorzystuje obiekt menedżera do tworzenia rekordu listy w procesie serwera, a następnie dodawania nowego rekordu do tej listy.

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()

Wynik

A New record is added

Name: Computers
Score: 1

Name: Histoty
Score: 5

Name: Hindi
Score: 9

Name: English
Score: 3

Pojęcie przestrzeni nazw w menedżerze

Manager Class zawiera koncepcję przestrzeni nazw, która jest szybką metodą udostępniania kilku atrybutów w wielu procesach. Przestrzenie nazw nie zawierają żadnej publicznej metody, którą można wywołać, ale mają atrybuty z możliwością zapisu.

Przykład

Poniższy przykład skryptu w języku Python pomaga nam wykorzystywać przestrzenie nazw do udostępniania danych w procesie głównym i podrzędnym -

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)

Wynik

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

Tablica Ctypes i wartość

Moduł wieloprocesorowy zapewnia obiekty Array i Value do przechowywania danych w mapie pamięci współdzielonej. Array jest tablicą ctypes przydzieloną z pamięci współdzielonej i Value jest obiektem ctypes przydzielonym z pamięci współdzielonej.

Aby być z, zaimportuj Process, Value, Array z przetwarzania wieloprocesowego.

Przykład

Poniższy skrypt w języku Python jest przykładem zaczerpniętym z dokumentacji Pythona w celu wykorzystania tablicy i wartości Ctypes do udostępniania niektórych danych między procesami.

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[:])

Wynik

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

Komunikowanie procesów sekwencyjnych (CSP)

CSP służy do zilustrowania interakcji systemów z innymi systemami wyposażonymi w modele współbieżne. CSP to framework do pisania współbieżnego lub programu poprzez przekazywanie komunikatów, dlatego jest skuteczny do opisywania współbieżności.

Biblioteka Pythona - PyCSP

Do implementacji podstawowych prymitywów znalezionych w CSP, Python ma bibliotekę o nazwie PyCSP. Dzięki temu implementacja jest bardzo krótka i czytelna, dzięki czemu można ją bardzo łatwo zrozumieć. Poniżej przedstawiono podstawową sieć procesową PyCSP -

W powyższej sieci procesów PyCSP istnieją dwa procesy - Proces1 i Proces 2. Procesy te komunikują się, przesyłając komunikaty przez dwa kanały - kanał 1 i kanał 2.

Instalowanie PyCSP

Za pomocą następującego polecenia możemy zainstalować bibliotekę Python PyCSP -

pip install PyCSP

Przykład

Poniższy skrypt w Pythonie jest prostym przykładem uruchamiania dwóch procesów równolegle względem siebie. Odbywa się to za pomocą biblioteki PyCSP Python -

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()

W powyższym skrypcie dwie funkcje, a mianowicie P1 i P2 zostały stworzone, a następnie ozdobione @process za przekształcenie ich w procesy.

Wynik

P2 exiting
P1 exiting
Terminating