Procesos de intercomunicación

La intercomunicación de procesos significa el intercambio de datos entre procesos. Es necesario intercambiar los datos entre procesos para el desarrollo de aplicaciones paralelas. El siguiente diagrama muestra los diversos mecanismos de comunicación para la sincronización entre múltiples subprocesos:

Varios mecanismos de comunicación

En esta sección, aprenderemos sobre los distintos mecanismos de comunicación. Los mecanismos se describen a continuación:

Colas

Las colas se pueden utilizar con programas multiproceso. La clase Queue demultiprocessing módulo es similar al Queue.Queueclase. Por tanto, se puede utilizar la misma API.Multiprocessing.Queue nos proporciona un mecanismo de comunicación entre procesos FIFO (primero en entrar, primero en salir) seguro para procesos y subprocesos.

Ejemplo

A continuación se muestra un ejemplo simple tomado de los documentos oficiales de Python sobre multiprocesamiento para comprender el concepto de clase de multiprocesamiento en cola.

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

Salida

[42, None, 'hello']

Tubería

Es una estructura de datos, que se utiliza para comunicarse entre procesos en programas multiproceso. La función Pipe () devuelve un par de objetos de conexión conectados por una tubería que por defecto es dúplex (bidireccional). Funciona de la siguiente manera:

  • Devuelve un par de objetos de conexión que representan los dos extremos de la tubería.

  • Cada objeto tiene dos métodos: send() y recv(), para comunicarse entre procesos.

Ejemplo

A continuación se muestra un ejemplo simple tomado de los documentos oficiales de Python sobre multiprocesamiento para comprender el concepto de Pipe() función de multiprocesamiento.

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

Salida

[42, None, 'hello']

Gerente

Manager es una clase de módulo de multiprocesamiento que proporciona una forma de coordinar la información compartida entre todos sus usuarios. Un objeto administrador controla un proceso de servidor, que administra objetos compartidos y permite que otros procesos los manipulen. En otras palabras, los gerentes brindan una forma de crear datos que se pueden compartir entre diferentes procesos. A continuación se muestran las diferentes propiedades del objeto administrador:

  • La propiedad principal del administrador es controlar un proceso del servidor, que administra los objetos compartidos.

  • Otra propiedad importante es la de actualizar todos los objetos compartidos cuando algún proceso lo modifica.

Ejemplo

A continuación se muestra un ejemplo que utiliza el objeto administrador para crear un registro de lista en el proceso del servidor y luego agregar un nuevo registro en esa lista.

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

Salida

A New record is added

Name: Computers
Score: 1

Name: Histoty
Score: 5

Name: Hindi
Score: 9

Name: English
Score: 3

Concepto de espacios de nombres en Manager

Manager Class viene con el concepto de espacios de nombres, que es un método de forma rápida para compartir varios atributos en múltiples procesos. Los espacios de nombres no presentan ningún método público al que se pueda llamar, pero tienen atributos de escritura.

Ejemplo

El siguiente ejemplo de secuencia de comandos de Python nos ayuda a utilizar espacios de nombres para compartir datos entre el proceso principal y el proceso secundario:

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)

Salida

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

Ctypes-Array y valor

El módulo de multiprocesamiento proporciona objetos Array y Value para almacenar los datos en un mapa de memoria compartida. Array es una matriz ctypes asignada desde la memoria compartida y Value es un objeto ctypes asignado desde la memoria compartida.

Para estar con, importar Process, Value, Array desde multiprocesamiento.

Ejemplo

El siguiente script de Python es un ejemplo tomado de los documentos de Python para utilizar Ctypes Array y Value para compartir algunos datos entre procesos.

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

Salida

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

Comunicación de procesos secuenciales (CSP)

CSP se utiliza para ilustrar la interacción de sistemas con otros sistemas que presentan modelos concurrentes. CSP es un marco para escribir programas o programas simultáneos mediante el paso de mensajes y, por lo tanto, es eficaz para describir la concurrencia.

Biblioteca de Python - PyCSP

Para implementar primitivas centrales que se encuentran en CSP, Python tiene una biblioteca llamada PyCSP. Mantiene la implementación muy breve y legible para que se pueda entender muy fácilmente. A continuación se muestra la red de procesos básica de PyCSP:

En la red de procesos PyCSP anterior, hay dos procesos: Proceso 1 y Proceso 2. Estos procesos se comunican pasando mensajes a través de dos canales: el canal 1 y el canal 2.

Instalación de PyCSP

Con la ayuda del siguiente comando, podemos instalar la biblioteca Python PyCSP -

pip install PyCSP

Ejemplo

El siguiente script de Python es un ejemplo simple para ejecutar dos procesos en paralelo entre sí. Se hace con la ayuda de la biblioteca Python PyCSP -

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

En el script anterior, dos funciones a saber P1 y P2 han sido creados y decorados con @process para convertirlos en procesos.

Salida

P2 exiting
P1 exiting
Terminating