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