Comunicación entre procesos (IPC) – Part 2

 

Un proceso puede ser de dos tipos:

  • Proceso independiente.
  • Proceso cooperativo.

Un proceso independiente no se ve afectado por la ejecución de otros procesos, mientras que un proceso cooperativo puede verse afectado por otros procesos en ejecución. Aunque uno puede pensar que esos procesos, que se ejecutan de forma independiente, se ejecutarán de manera muy eficiente, en realidad, hay muchas situaciones en las que la naturaleza cooperativa se puede utilizar para aumentar la velocidad computacional, la conveniencia y la modularidad. La comunicación entre procesos (IPC) es un mecanismo que permite que los procesos se comuniquen entre sí y sincronicen sus acciones. La comunicación entre estos procesos puede verse como un método de cooperación entre ellos. Los procesos pueden comunicarse entre sí a través de ambos:
 

  1. Memoria compartida
  2. Paso de mensajes

La figura 1 a continuación muestra una estructura básica de comunicación entre procesos mediante el método de memoria compartida y mediante el método de paso de mensajes. 
 

 

Un sistema operativo puede implementar ambos métodos de comunicación. Primero, discutiremos los métodos de comunicación de memoria compartida y luego el paso de mensajes. La comunicación entre procesos que usan memoria compartida requiere que los procesos compartan alguna variable, y depende completamente de cómo la implementará el programador. Una forma de comunicación usando la memoria compartida se puede imaginar así: suponga que el proceso 1 y el proceso 2 se ejecutan simultáneamente y comparten algunos recursos o usan información de otro proceso. Process1 genera información sobre ciertos cálculos o recursos que se utilizan y la mantiene como un registro en la memoria compartida. Cuando el proceso2 necesite usar la información compartida, verificará el registro almacenado en la memoria compartida y tomará nota de la información generada por el proceso1 y actuará en consecuencia. 
Analicemos un ejemplo de comunicación entre procesos usando el método de memoria compartida.
 

i) Método de memoria compartida

Ejemplo: Problema productor-consumidor 
Hay dos procesos: Productor y Consumidor. El productor produce algunos artículos y el Consumidor consume ese artículo. Los dos procesos comparten un espacio común o ubicación de memoria conocida como búfer donde se almacena el artículo producido por el Productor y desde el cual el Consumidor consume el artículo si es necesario. Hay dos versiones de este problema: la primera se conoce como el problema del búfer ilimitado en el que el Productor puede seguir produciendo artículos y no hay límite en el tamaño del búfer, la segunda se conoce como el problema del búfer limitado en que el Productor puede producir hasta un cierto número de artículos antes de comenzar a esperar que el Consumidor lo consuma. Discutiremos el problema del búfer acotado. Primero, el Productor y el Consumidor compartirán una memoria común, luego el productor comenzará a producir artículos. Si el artículo total producido es igual al tamaño del búfer, el productor esperará a que el consumidor lo consuma. Del mismo modo, el consumidor verificará primero la disponibilidad del artículo. Si no hay ningún artículo disponible, el Consumidor esperará a que el Productor lo produzca. Si hay artículos disponibles, el Consumidor los consumirá. El pseudocódigo para demostrar se proporciona a continuación:
Datos Compartidos entre los dos Procesos 
 

C

#define buff_max 25
#define mod %
 
    struct item{
 
        // different member of the produced data
        // or consumed data   
        ---------
    }
     
    // An array is needed for holding the items.
    // This is the shared place which will be 
    // access by both process  
    // item shared_buff [ buff_max ];
      
    // Two variables which will keep track of
    // the indexes of the items produced by producer
    // and consumer The free index points to
    // the next free index. The full index points to
    // the first full index.
    int free_index = 0;
    int full_index = 0;
  

Código de proceso del productor 
 

C

item nextProduced;
     
    while(1){
         
        // check if there is no space
        // for production.
        // if so keep waiting.
        while((free_index+1) mod buff_max == full_index);
         
        shared_buff[free_index] = nextProduced;
        free_index = (free_index + 1) mod buff_max;
    }

Código de proceso del consumidor 
 

C

item nextConsumed;
     
    while(1){
         
        // check if there is an available
        // item  for consumption.
        // if not keep on waiting for
        // get them produced.
        while((free_index == full_index);
         
        nextConsumed = shared_buff[full_index];
        full_index = (full_index + 1) mod buff_max;
    }

En el código anterior, el Productor comenzará a producir nuevamente cuando el mod buff max (free_index+1) sea gratuito porque si no lo es, esto implica que todavía hay elementos que el Consumidor puede consumir, por lo que no es necesario. para producir más. De manera similar, si el índice libre y el índice completo apuntan al mismo índice, esto implica que no hay artículos para consumir.
 

ii) Método de transferencia de mensajes

Ahora, comenzaremos nuestra discusión sobre la comunicación entre procesos a través del paso de mensajes. En este método, los procesos se comunican entre sí sin utilizar ningún tipo de memoria compartida. Si dos procesos p1 y p2 quieren comunicarse entre sí, proceden de la siguiente manera:
 

  • Establezca un enlace de comunicación (si ya existe un enlace, no es necesario volver a establecerlo).
  • Comience a intercambiar mensajes utilizando primitivas básicas.
    Necesitamos al menos dos primitivas: 
    enviar (mensaje, destino) o enviar (mensaje) 
    recibir (mensaje, anfitrión) o recibir (mensaje)

El tamaño del mensaje puede ser de tamaño fijo o de tamaño variable. Si es de tamaño fijo, es fácil para un diseñador de SO pero complicado para un programador y si es de tamaño variable entonces es fácil para un programador pero complicado para el diseñador de SO. Un mensaje estándar puede tener dos partes: encabezado y cuerpo.  
La parte del encabezado se utiliza para almacenar el tipo de mensaje, la identificación del destino, la identificación de la fuente, la longitud del mensaje y la información de control. La información de control contiene información como qué hacer si se queda sin espacio de búfer, número de secuencia, prioridad. Generalmente, el mensaje se envía utilizando el estilo FIFO.
  

Mensaje que pasa a través del enlace de comunicación.
Enlace de comunicación directa e indirecta 
Ahora, comenzaremos nuestra discusión sobre los métodos para implementar enlaces de comunicación. Al implementar el enlace, hay algunas preguntas que deben tenerse en cuenta, como: 
 

  1. ¿Cómo se establecen los vínculos?
  2. ¿Se puede asociar un enlace a más de dos procesos?
  3. ¿Cuántos enlaces puede haber entre cada par de procesos comunicantes?
  4. ¿Cuál es la capacidad de un enlace? ¿El tamaño de un mensaje que el enlace puede acomodar es fijo o variable?
  5. ¿Un enlace es unidireccional o bidireccional?

Un enlace tiene cierta capacidad que determina la cantidad de mensajes que pueden residir en él temporalmente, por lo que cada enlace tiene una cola asociada que puede tener capacidad cero, capacidad limitada o capacidad ilimitada. En capacidad cero, el remitente espera hasta que el receptor informa al remitente que ha recibido el mensaje. En casos de capacidad distinta de cero, un proceso no sabe si un mensaje ha sido recibido o no después de la operación de envío. Para ello, el remitente debe comunicarse con el receptor de forma explícita. La implementación del enlace depende de la situación, puede ser un enlace de comunicación directo o un enlace de comunicación indirecto. 
Enlaces de comunicación directase implementan cuando los procesos usan un identificador de proceso específico para la comunicación, pero es difícil identificar al remitente con anticipación. 
Por ejemplo, el servidor de impresión.
La comunicación indirecta se realiza a través de un buzón compartido (puerto), que consta de una cola de mensajes. El remitente guarda el mensaje en el buzón y el receptor lo recoge.
 

Mensaje que pasa a través del intercambio de mensajes.

Paso de mensajes síncrono y asíncrono: 
un proceso que está bloqueado es uno que está esperando algún evento, como que un recurso esté disponible o la finalización de una operación de E/S. IPC es posible entre los procesos en la misma computadora, así como en los procesos que se ejecutan en una computadora diferente, es decir, en un sistema en red/distribuido. En ambos casos, el proceso puede bloquearse o no mientras se envía un mensaje o se intenta recibir un mensaje, por lo que el paso de mensajes puede bloquearse o no bloquearse. El bloqueo se considera síncrono y el bloqueo de envío significa que el remitente será bloqueado hasta que el receptor reciba el mensaje. De manera similar, bloquear la recepción hace que el receptor bloquee hasta que haya un mensaje disponible. Se considera no bloqueanteEl envío asíncrono y sin bloqueo hace que el remitente envíe el mensaje y continúe. De manera similar, la recepción sin bloqueo hace que el receptor reciba un mensaje válido o nulo. Después de un análisis cuidadoso, podemos llegar a la conclusión de que para un remitente es más natural no bloquear después de pasar el mensaje, ya que puede ser necesario enviar el mensaje a diferentes procesos. Sin embargo, el remitente espera la confirmación del receptor en caso de que falle el envío. De manera similar, es más natural que un receptor se bloquee después de emitir la recepción, ya que la información del mensaje recibido puede usarse para una ejecución posterior. Al mismo tiempo, si el envío del mensaje sigue fallando, el receptor deberá esperar indefinidamente. Es por eso que también consideramos la otra posibilidad de pasar mensajes. Hay básicamente tres combinaciones preferidas:
 

  • Bloqueo de envío y bloqueo de recepción
  • Envío sin bloqueo y recepción sin bloqueo
  • Envío sin bloqueo y recepción con bloqueo (más utilizados)

En el paso directo de mensajes , el proceso que desea comunicarse debe nombrar explícitamente al destinatario o remitente de la comunicación. 
por ejemplo, enviar (p1, mensaje) significa enviar el mensaje a p1. 
De manera similar, recibir (p2, mensaje) significa recibir el mensaje de p2. 
En este método de comunicación, el enlace de comunicación se establece automáticamente, que puede ser unidireccional o bidireccional, pero se puede usar un enlace entre un par de emisor y receptor y un par de emisor y receptor no debe poseer más de un par de Enlaces. También se puede implementar la simetría y la asimetría entre el envío y la recepción, es decir, ambos procesos se nombrarán entre sí para enviar y recibir los mensajes o solo el remitente nombrará al receptor para enviar el mensaje y no es necesario que el receptor nombre al remitente para recibiendo el mensaje. El problema con este método de comunicación es que si cambia el nombre de un proceso, este método no funcionará.
En el paso de mensajes indirectos, los procesos utilizan buzones (también denominados puertos) para enviar y recibir mensajes. Cada buzón tiene una identificación única y los procesos pueden comunicarse solo si comparten un buzón. Enlace establecido solo si los procesos comparten un buzón común y un solo enlace puede asociarse con muchos procesos. Cada par de procesos puede compartir varios enlaces de comunicación y estos enlaces pueden ser unidireccionales o bidireccionales. Supongamos que dos procesos quieren comunicarse a través del paso de mensajes indirectos, las operaciones requeridas son: crear un buzón, usar este buzón para enviar y recibir mensajes, luego destruir el buzón. Las primitivas estándar utilizadas son: enviar (A, mensaje) que significa enviar el mensaje al buzón A. La primitiva para recibir el mensaje también funciona de la misma manera, por ejemplo, recibido (A, mensaje). Hay un problema con esta implementación de buzón. Supongamos que hay más de dos procesos compartiendo el mismo buzón y supongamos que el proceso p1 envía un mensaje al buzón, ¿cuál proceso será el receptor? Esto se puede resolver haciendo cumplir que solo dos procesos pueden compartir un solo buzón o haciendo cumplir que solo un proceso puede ejecutar la recepción en un momento dado o seleccionando cualquier proceso al azar y notificando al remitente sobre el receptor. Un buzón se puede hacer privado para un solo par de remitente/receptor y también se puede compartir entre varios pares de remitente/receptor. El puerto es una implementación de dicho buzón que puede tener múltiples remitentes y un solo receptor. Se utiliza en aplicaciones cliente/servidor (en este caso el servidor es el receptor). El puerto es propiedad del proceso receptor y lo crea el sistema operativo a petición del proceso receptor y puede destruirse a petición del mismo procesador receptor cuando el receptor finaliza. Hacer cumplir que solo un proceso puede ejecutar la recepción se puede hacer utilizando el concepto de exclusión mutua.Se crea un buzón de exclusión mutua que es compartido por n proceso. El remitente no bloquea y envía el mensaje. El primer proceso que ejecuta la recepción entrará en la sección crítica y todos los demás procesos se bloquearán y esperarán.
Ahora, analicemos el problema Productor-Consumidor utilizando el concepto de paso de mensajes. El productor coloca elementos (mensajes internos) en el buzón y el consumidor puede consumir un elemento cuando al menos un mensaje está presente en el buzón. El código se proporciona a continuación:
Código del productor 
 

C

void Producer(void){
         
        int item;
        Message m;
         
        while(1){
             
            receive(Consumer, &m);
            item = produce();
            build_message(&m , item ) ;
            send(Consumer, &m);
        }
    }

Código del Consumidor 
 

C

void Consumer(void){
         
        int item;
        Message m;
         
        while(1){
             
            receive(Producer, &m);
            item = extracted_item();
            send(Producer, &m);
            consume_item(item);
        }
    }

Ejemplos de sistemas IPC 
 

  1. Posix: utiliza el método de memoria compartida.
  2. Mach: utiliza el paso de mensajes
  3. Windows XP: utiliza el paso de mensajes mediante llamadas de procedimiento locales

Comunicación en Arquitectura cliente/servidor:
Existen varios mecanismos: 
 

  • Tubo
  • Enchufe
  • Llamadas de procedimiento remotas (RPC)

Los tres métodos anteriores se discutirán en artículos posteriores, ya que todos ellos son bastante conceptuales y merecen sus propios artículos separados.
Referencias: 
 

  1. Conceptos de sistemas operativos por Galvin et al.
  2. Apuntes de clase/ppt de Ariel J. Frank, Universidad Bar-Ilan

Más referencia: 
http://nptel.ac.in/courses/106108101/pdf/Lecture_Notes/Mod%207_LN.pdf  
https://www.youtube.com/watch?v=lcRqHwIn5Dk
Este artículo es una contribución de Durgesh Pandey . Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente. Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo y enviarlo por correo electrónico a contribuya@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *