Linux tiene un conocimiento profundo de la comunicación multiproceso

1. Comunicación entre procesos

1.1 Propósito de la comunicación entre procesos

  • Transferencia de datos : un proceso necesita enviar sus datos a otro proceso.
  • Compartir recursos : compartir los mismos recursos entre múltiples procesos.
  • Evento de notificación : un proceso necesita enviar un mensaje a otro proceso o a un grupo de procesos para notificarles que ha ocurrido un determinado evento (como notificar al proceso principal cuando finaliza el proceso).
  • Control de procesos : Algunos procesos esperan controlar completamente la ejecución de otro proceso (como el proceso de depuración), en este momento el proceso de control espera interceptar todas las trampas y excepciones de otro proceso y poder conocer sus cambios de estado a tiempo. 
数据传输:一个进程需要将它的数据发送给另一个进程
资源共享:多个进程之间共享同样的资源。
通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止
时要通知父进程)。
进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另
一个进程的所有陷入和异常,并能够及时知道它的状态改变。

1.2 Desarrollo de la comunicación entre procesos. 

  • tubería
  • Comunicación entre procesos del Sistema V
  • Comunicación entre procesos POSIX

1.3 Clasificación de la comunicación entre procesos.

1.3.1 Tubería

  • tubería anónima
  • tubería con nombre

1.3.2 IPC del Sistema V

  • Cola de mensajes del sistema V
  • Memoria compartida del sistema V
  • Semáforo del sistema V

1.3.3 IPC POSIX

  • cola de mensajes
  • Memoria compartida
  • Cantidad de señal
  • exclusión mutua
  • variable de condición
  • bloqueo de lectura-escritura

2. Tubería (relacionada)

Las canalizaciones son la forma más antigua de comunicación entre procesos en Unix.

Llamamos "canalización" al flujo de datos de un proceso a otro.

2.1 Utilice fork para compartir principios de canalización

2.2 Tubería anónima 

#include <unistd.h>
功能:创建一无名管道
原型
int pipe(int fd[2]);
参数
fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端
返回值:成功返回0,失败返回错误代码

Código de ejemplo 

打开管道
获取键盘stdin的数据读到buf中
把buf中的数据写到管道中
从管道中把数据写到回buf中
再把buf中的数据写到stdout中

2.3 Desde la perspectiva de los descriptores de archivos: comprensión profunda de las canalizaciones

2.4 Desde la perspectiva del kernel: la esencia de las tuberías 

Por lo tanto, ¡trate las tuberías como si fueran limas! El uso de canalizaciones es consistente con archivos, lo que satisface la idea de "Linux todo es una idea de archivo". 

Agregue la implementación de la canalización en my_shell:

添加功能

2.5 Reglas de lectura y escritura de tuberías

当没有数据可读时
O_NONBLOCK disable:read调用阻塞,即进程暂停执行,一直等到有数据来到为止。
O_NONBLOCK enable:read调用返回-1,errno值为EAGAIN。
当管道满的时候
O_NONBLOCK disable: write调用阻塞,直到有进程读走数据
O_NONBLOCK enable:调用返回-1,errno值为EAGAIN
如果所有管道写端对应的文件描述符被关闭,则read返回0
如果所有管道读端对应的文件描述符被关闭,则write操作会产生信号SIGPIPE,进而可能导致write进程
退出
当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。
当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。

2.6 Características de la tubería

En Linux, si el descriptor de archivo de una canalización anónima está cerrado, no se puede volver a abrir, por lo que sólo se puede lograr una comunicación unidireccional.

只能用于具有共同祖先的进程(具有亲缘关系的进程)之间进行通信;通常,一个管道由一个进程创
建,然后该进程调用fork,此后父、子进程之间就可应用该管道。
管道提供流式服务
一般而言,进程退出,管道释放,所以管道的生命周期随进程
一般而言,内核会对管道操作进行同步与互斥
管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道

3. Tuberías con nombre

  • Una limitación de las aplicaciones de canalización es que sólo pueden comunicarse entre procesos que tienen un ancestro común (relacionados entre sí).
  • Si queremos intercambiar datos entre procesos no relacionados, podemos usar archivos FIFO para hacer el trabajo, que a menudo se denominan canalizaciones con nombre.
  • Una canalización con nombre es un tipo especial de archivo

3.1 Crear una tubería con nombre

Crear usando la línea de comando

mkfifo filename

Crear en código

int mkfifo(const char *filename,mode_t mode);

Los permisos reales se ven afectados por umask

La diferencia entre canalizaciones anónimas y canalizaciones con nombre

匿名管道由pipe函数创建并打开。
命名管道由mkfifo函数创建,打开用open
FIFO(命名管道)与pipe(匿名管道)之间唯一的区别在它们创建与打开的方式不同,一但这些工作完
成之后,它们具有相同的语义。

Reglas de apertura de tuberías con nombre

如果当前打开操作是为读而打开FIFO时
O_NONBLOCK disable:阻塞直到有相应进程为写而打开该FIFO
O_NONBLOCK enable:立刻返回成功
如果当前打开操作是为写而打开FIFO时
O_NONBLOCK disable:阻塞直到有相应进程为读而打开该FIFO
O_NONBLOCK enable:立刻返回失败,错误码为ENXIO

Experimento 1: Copia de archivos usando canalizaciones con nombre

Experimento 2: utilice canalizaciones con nombre para implementar la comunicación entre el servidor y el cliente

3. memoria compartida del sistema V

Las áreas de memoria compartida son la forma más rápida de IPC. Una vez que dicha memoria se asigna al espacio de direcciones del proceso que la comparte, estas transferencias de datos entre procesos ya no involucran al núcleo. En otras palabras, los procesos ya no se transfieren datos entre sí mediante la ejecución de llamadas al sistema en el núcleo.

Estructura de datos de memoria compartida

struct shmid_ds {
 struct ipc_perm shm_perm; /* operation perms */
 int shm_segsz; /* size of segment (bytes) */
 __kernel_time_t shm_atime; /* last attach time */
 __kernel_time_t shm_dtime; /* last detach time */
 __kernel_time_t shm_ctime; /* last change time */
 __kernel_ipc_pid_t shm_cpid; /* pid of creator */
 __kernel_ipc_pid_t shm_lpid; /* pid of last operator */
 unsigned short shm_nattch; /* no. of current attaches */
 unsigned short shm_unused; /* compatibility */
 void *shm_unused2; /* ditto - used by DIPC */
 void *shm_unused3; /* unused */
};

 

Funciones de memoria compartida

función shmget

功能:用来创建共享内存
原型
 int shmget(key_t key, size_t size, int shmflg);
参数
 key:这个共享内存段名字
 size:共享内存大小
 shmflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的
返回值:成功返回一个非负整数,即该共享内存段的标识码;失败返回-1

función shmat

功能:将共享内存段连接到进程地址空间
原型
 void *shmat(int shmid, const void *shmaddr, int shmflg);
参数
 shmid: 共享内存标识
 shmaddr:指定连接的地址
 shmflg:它的两个可能取值是SHM_RND和SHM_RDONLY
返回值:成功返回一个指针,指向共享内存第一个节;失败返回-1

shmaddr为NULL,核心自动选择一个地址
shmaddr不为NULL且shmflg无SHM_RND标记,则以shmaddr为连接地址。
shmaddr不为NULL且shmflg设置了SHM_RND标记,则连接的地址会自动向下调整为SHMLBA的整数倍。公式:shmaddr - 
(shmaddr % SHMLBA)
shmflg=SHM_RDONLY,表示连接操作用来只读共享内存

función shmdt

功能:将共享内存段与当前进程脱离
原型
 int shmdt(const void *shmaddr);
参数
 shmaddr: 由shmat所返回的指针
返回值:成功返回0;失败返回-1
注意:将共享内存段与当前进程脱离不等于删除共享内存段

función shmctl

功能:用于控制共享内存
原型
 int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数
 shmid:由shmget返回的共享内存标识码
 cmd:将要采取的动作(有三个可取值)
 buf:指向一个保存着共享内存的模式状态和访问权限的数据结构
返回值:成功返回0;失败返回-1

cmd

IPC_STAT: obtiene el estado de la memoria compartida y copia la estructura shmid_ds de la memoria compartida a buf

IPC_SET: cambia el estado de la memoria compartida y copia el uid, gid y el modo en la estructura shmid_ds apuntada por buf a la estructura shmid_ds de la memoria compartida.

IPC_RMID: Eliminar esta memoria compartida

 

  • La clave es la clave de la memoria compartida;
  • shmid es el número de memoria compartida;
  • semid es el número de la matriz de semáforos;
  • nsems corresponde al número de semáforos en el conjunto de semáforos
  • pid es la ip del proceso, puedes ver los detalles a través de ps -ef | grep pid
  • semnum es el número del semáforo
  • ncount es el número de procesos que esperan la señal
  • El propietario es el usuario que lo creó;
  • Los permisos también se denominan permisos;
  • Bytes es el tamaño de bytes creado;
  • El número de conexiones es el número de procesos conectados a la memoria compartida nattach;
  • El estado es el estado de la memoria compartida.
     

Cuarto, cola de mensajes del sistema V

5. semáforo del sistema V

6. Proceso de exclusión mutua

  • Dado que cada proceso requiere recursos compartidos y algunos recursos deben usarse de manera mutuamente excluyente, los procesos compiten por usar estos recursos.Esta relación entre procesos es la exclusión mutua de los procesos.
  • Algunos recursos del sistema solo pueden ser utilizados por un proceso a la vez y se denominan recursos críticos o recursos mutuamente excluyentes. La sección del programa que involucra recursos mutuamente excluyentes en el proceso se llama sección crítica.
  • Características: los recursos IPC deben eliminarse; de ​​lo contrario, no se borrarán automáticamente a menos que se reinicie, por lo que el ciclo de vida de los recursos IPC del sistema V depende del kernel.

Supongo que te gusta

Origin blog.csdn.net/m0_74234485/article/details/132646671
Recomendado
Clasificación