Red de conocimiento informático - Aprendizaje de programación - Comunicación entre procesos de Linux

Comunicación entre procesos de Linux

Presentamos algunos de los principales métodos de comunicación entre procesos en Linux:

Las tuberías pueden usar funciones generales de E/S de archivos, como cerrar, leer, escribir, etc.

Ejemplo 1: para shell

Las canalizaciones se pueden utilizar para la redirección de entrada y salida, es decir, la salida de un comando se dirige a la entrada de otro comando. Por ejemplo, cuando ingresa who│wc -l en un programa shell (shell Bourne o shell C, etc.), el programa shell correspondiente creará dos procesos: who y wc, y establecerá una tubería entre ellos.

Ejemplo 2: Comunicación entre procesos con procesos relacionados

La principal limitación de las tuberías son sus características:

Creación de tuberías con nombre

Resumen:

Las tuberías generalmente se utilizan de dos maneras. (1) En el shell, las canalizaciones se utilizan a menudo (como redirección de entrada), donde la creación de la canalización es transparente para el usuario (2) para la comunicación entre procesos con familiares, donde el usuario crea la canalización y lee; y lo escribe él mismo.

Se puede decir que FIFO es una versión mejorada de la tubería. Supera las limitaciones de la tubería sin nombre y permite que los procesos no asociados se comuniquen utilizando el mecanismo de comunicación primero en entrar, primero en salir.

Tanto los pipes como los FIFO son flujos de bytes y se debe definir de antemano un "protocolo" de transmisión específico entre aplicaciones para propagar mensajes con significados específicos.

Comprender las reglas de lectura y escritura de pipes y FIFO es la clave para utilizarlos de forma flexible.

Ciclo de vida de la señal

Las señales son el único mecanismo de comunicación asincrónico entre procesos y pueden considerarse notificaciones asincrónicas, notificando al proceso que recibe la señal lo que sucedió. POSIX Real-Time amplía el mecanismo de señalización para hacerlo más potente, permitiendo pasar más información además de las capacidades de notificación básicas.

Las señales se pueden clasificar desde dos perspectivas diferentes: (1) confiabilidad: señales confiables y señales no confiables; (2) relación con el tiempo: señales en tiempo real y señales en tiempo no real.

(1) Señal confiable y señal no confiable

Señal no confiable: el problema de la señal no confiable en Linux se refiere principalmente a la posibilidad de pérdida de señal.

Señal confiable: Una señal con un valor de señal entre SIGRTMIN y SIGRTMAX es una señal confiable. Una señal confiable supera el problema de una posible pérdida de señal. Linux admite nuevas versiones del instalador de señales sigation() y del remitente de señales sigqueue(), al mismo tiempo que admite la función anterior del instalador de señales y la función de señal kill().

Para las dos funciones de instalación de señales en Linux actual: signal() y sigaction(), no pueden convertir señales anteriores a SIGRTMIN en señales confiables (ambas no admiten colas y aún pueden perderse, aún son señales poco confiables). ), mientras que las colas son compatibles con señales posteriores a SIGRTMIN. La mayor diferencia entre estas dos funciones es que las señales instaladas a través de sigaction pueden pasar información a las funciones de manejo de señales (esto se aplica a todas las señales), mientras que las señales instaladas a través de señales no pueden pasar información a las funciones de manejo de señales. Lo mismo ocurre con la función de señal.

(2) Señales en tiempo real y señales en tiempo no real

Las primeras 32 señales tienen valores predefinidos, cada señal tiene un propósito y significado determinados, y cada señal tiene su propio acción predeterminada. Por ejemplo, presionar la tecla CTRL ^C en el teclado genera una señal SIGINT y la respuesta predeterminada es que el proceso finaliza. Las últimas 32 señales representan señales en tiempo real y son equivalentes a las señales confiables explicadas anteriormente. Esto garantiza que se reciban múltiples señales enviadas en tiempo real. Las señales en tiempo real son parte del estándar POSIX y están disponibles para los procesos de aplicación. Las señales que no son en tiempo real no admiten colas y no son señales confiables; todas las señales en tiempo real admiten colas y son señales confiables.

Las funciones principales para el envío de señales son kill(), rise(), sigqueue(), alarm(), setitimer() y abort().

Devuelve 0 si la llamada es exitosa, en caso contrario -1.

sigqueue() es una llamada al sistema relativamente nueva para enviar señales. Se utiliza principalmente para señales en tiempo real (por supuesto, las primeras 32 señales también son compatibles con señales con parámetros). la función sigaction() Se utiliza en combinación.

El primer parámetro de sigqueue especifica el ID del proceso de la señal que se recibe, el segundo parámetro identifica la señal que se enviará y el tercer parámetro es una estructura de datos de unión union sigval, que especifica los parámetros de la señal. transmisión, generalmente Se refiere a un valor de 4 bytes.

sigqueue() pasa más información adicional que kill(), pero sigqueue() solo puede enviar una señal a un proceso.

Linux tiene dos funciones principales para implementar la transmisión de señales: signal() y sigaction(). Entre ellos, signal() se implementa además de llamadas confiables al sistema de señales y es una función de biblioteca. Tiene solo dos parámetros y no admite información de señalización. Se utiliza principalmente para instalar las primeras 32 señales que no son en tiempo real; mientras que sigaction() es una función más nueva (implementada por dos llamadas al sistema: sys_signal y sys_rt_sigaction) y tiene tres. parámetros., admite información de señalización, utilizada principalmente junto con la llamada al sistema sigqueue(). Por supuesto, la llamada al sistema sigqueue() y sigaction() también admiten la instalación de señalización no en tiempo real. La razón principal por la que sigaction() es superior a signal() es que admite señalización con parámetros.

Una cola de mensajes es una lista enlazada de mensajes. Un mensaje puede verse como un registro con un formato y una prioridad específicos. Un proceso con acceso de escritura a la cola de mensajes puede agregar nuevos mensajes a la cola de acuerdo con reglas específicas; un proceso con acceso de lectura a la cola de mensajes puede leer mensajes de la cola. Las colas de mensajes tienen persistencia del kernel

La persistencia del kernel para las colas de mensajes requiere que cada cola de mensajes corresponda a un valor clave único en todo el sistema, por lo que para obtener el descriptor de una cola de mensajes, solo necesita proporcionar la cola de mensajes. El valor clave es suficiente;

La cola de mensajes tiene mayor flexibilidad que las canalizaciones y las canalizaciones con nombre. En primer lugar, proporciona un flujo de bytes formateado, lo que ayuda a reducir la carga de trabajo del desarrollador. En primer lugar, proporciona un flujo de bytes formateado, lo que ayuda a reducir la carga de trabajo del desarrollador; en segundo lugar, los mensajes se escriben y se pueden utilizar como prioridades en aplicaciones prácticas. Estos dos puntos son incomparables con la línea de montaje y la famosa línea de montaje. De manera similar, la cola de mensajes se puede reutilizar en múltiples procesos, estén relacionados o no, lo cual es similar al famoso pipe pero la cola de mensajes es persistente con el kernel, que es más viable que el famoso pipe (que es persistente con; el proceso). También hay un mayor espacio de aplicación.

Semaphore se diferencia de otros métodos de comunicación entre procesos. Proporciona principalmente un mecanismo de control de acceso a recursos de derechos entre procesos. Es equivalente a una bandera en la memoria. El proceso puede determinar si se puede acceder a ciertos recursos de los que disfruta **** en función de esta bandera. Al mismo tiempo, el proceso también puede modificar la bandera. Además de utilizarse para el control de acceso, también se puede utilizar para la sincronización de procesos. Hay dos tipos de semáforos:

int semop(int semid, struct sembuf *sops, unsigned nsops); semid es el ID de configuración del semáforo, sops apunta a una matriz, en la que cada estructura de sembuf registra lo específico. operación de semáforo.

int semctl(int semid, int semnum, int cmd, union semun arg)

Esta llamada al sistema implementa varias operaciones de control en señales. El parámetro semid especifica la colección del montón de señales, el. el parámetro cmd especifica el tipo de operación específico; el parámetro semnum especifica en qué pila de señales operar; el parámetro semnum especifica en qué pila de señales operar; solo algunas operaciones especiales de cmd son significativas para configurar o devolver información de la pila de señales;

Los datos que deben disfrutarse entre procesos se colocan en un lugar llamado área de memoria disfrutada de IPC. Todos los procesos que necesitan acceder al área disfrutada deben. El área disfrutada se asigna al espacio de direcciones de este proceso. La memoria compartida del sistema V**** obtiene o crea el área de memoria compartida IPC**** a través de shmget y devuelve el identificador correspondiente. Mientras garantiza que shmget obtenga o cree el área de memoria compartida IPC**** e inicialice la estructura shmid_kernel correspondiente del área de memoria compartida IPC****, el kernel también crea y abre un archivo con el mismo nombre en el sistema de archivos especial. shm y lo almacena en la memoria. Establezca la estructura de inodo y dentry correspondiente del archivo, y el archivo recién abierto no pertenece a ningún proceso (el archivo recién abierto no pertenece a ningún proceso (cualquier proceso puede acceder a la memoria compartida). área). Todos estos se pueden llamar a través del sistema shmget para completar.

shmget() se usa para obtener el ID del área de memoria disfrutada si el **** especificado. -el área disfrutada no existe, creará el área correspondiente shmat () Asigna la región de memoria disfrutada al espacio de direcciones del proceso de llamada para que pueda acceder fácilmente a la región disfrutada. shmdt() para desasignar la región de memoria que disfruta **** mediante la llamada shmctl. Se utiliza para desasignar la región de memoria que disfruta ****. Describa estas llamadas al sistema y, en su lugar, remita al lector a la página de manual correspondiente y los ejemplos que siguen le darán una idea de cómo se realizan estas llamadas.

Nota: La implementación interna de shmget contiene muchas. Mecanismos importantes de utilización de memoria del sistema V***; shmat se utiliza al mapear áreas de memoria ***** en el espacio del proceso, en realidad no cambia la tabla de páginas del proceso cuando el proceso accede al área de mapeo de memoria. Dado que no hay una tabla de páginas físicas para la asignación, se producirá una excepción de falla de página y luego el núcleo asignará la tabla de páginas correspondiente de acuerdo con el mecanismo de administración de almacenamiento correspondiente. >