XSI -> SysV
IPC -> Inter process communication 进程间通信的三种机制
主动端:先发包的一方
被动端:先收包的一方 ,一定是被动端先运行 等着收包
mhr@ubuntu:~/Desktop/xitongbiancheng/communication$ ipcs
Message Queues 消息队列 ,双工
key msqid owner perms used-bytes messages
msgget();
msgop();
msgctl();
Shared Memory Segments 信号量数组
key shmid owner perms bytes nattch status
Semaphore Arrays 共享内存
key semid owner perms nsems
Acerca del valor clave:
clave: ftok (), genera el valor de la clave IPC, convierte el nombre de la ruta y el identificador del proyecto en la clave IPC de System V
NAME
ftok - convert a pathname and a project identifier to a System V IPC key
SYNOPSIS
#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
El parámetro fname es el nombre de archivo especificado. Este archivo debe existir y ser accesible. id es el número de subsecuencia, que es un entero de 8 bits. Es decir, el rango es 0 ~ 255. Cuando la función se ejecuta con éxito, devolverá el valor key_t; de lo contrario, devolverá -1. En general UNIX, el nodo de índice del archivo generalmente se elimina y luego el número de subsecuencia se agrega al frente para obtener el valor de key_t.
msgget (): se utiliza para crear una nueva cola de mensajes u obtener una cola de mensajes existente
NAME
msgget - get a System V message queue identifier 获取一个消息队列的ID
SYNOPSIS
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
/ *
clave: el valor de la clave de la cola de mensajes. La función lo compara con la clave del objeto de la cola de mensajes existente para determinar si se ha creado el objeto de la cola de mensajes.
msgflg: la designación especial para crear la cola de mensajes actual
IPC_CREAT:如果消息队列对象不存在,则创建之,否则则进行打开操作;
IPC_EXCL:和IPC_CREAT 一起使用(用”|”连接),如果消息对象不存在则创建,否则产生一个错误并返回。
* /
int msgget(key_t key, int msgflg);
RETURN VALUE
If successful, the return value will be the message queue identifier (a nonnegative integer), otherwise -1 with errno indicating the error.
Si la bandera IPC_CREAT se usa sola, la función msgget () devolverá el identificador de un objeto de cola de mensajes existente o el identificador de un objeto de cola de mensajes recién creado. Si los indicadores IPC_CREAT e IPC_EXCL se usan juntos, msgget () devolverá el identificador de un objeto de mensaje recién creado, o -1 si el objeto de cola de mensajes ya existe. El indicador IPC_EXCL en sí mismo no tiene mucho significado, pero se puede utilizar junto con el indicador IPC_CREAT para garantizar que el objeto de cola de mensajes resultante sea un objeto recién creado en lugar de un objeto existente que esté abierto.
msgsnd (), msgrcv (): enviar y recibir mensajes en cola
NAME
msgrcv, msgsnd - System V message queue operations
SYNOPSIS
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
//发送
/*
msqid:消息队列ID
msgp :待发送数据位置
msgsz :待发送数据大小
msgflg :特殊要求
*/
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
//接收
/*
msqid:消息队列ID
msgp :收取消息存放位置,注意空间格式
msgsz :真正收取有效数据信息的大小,而不是全部的数据信息大小:sizeof(rbuf)-sizeof(long)
msgtyp:是否挑选消息来接收,比如接收第几个包,所以msg消息队列本质上已经不算是队列了,因为队列一定是先进先出。
msgflg:特殊指定操作
*/
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msgflg);
注意:
The msgp argument is a pointer to a caller-defined structure of the following general form:
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
RETURN VALUE
On failure both functions return -1 with errno indicating the error, otherwise msgsnd() returns 0 and msgrcv() returns the number of bytes actually copied into the mtext array.
msgctl (): controla una cola de mensajes, como destrucción, configuración, etc.
NAME
msgctl - System V message control operations
SYNOPSIS
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
/* 对消息队列msqid 执行 cmd命令,buf表示是否需要传参
cmd:
IPC_STAT
IPC_SET
IPC_RMID 删除当前消息队列
IPC_INFO (Linux-specific)
MSG_INFO (Linux-specific)
MSG_STAT (Linux-specific)
*/
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
Experimento: cola de mensajes de comunicación entre procesos, aquí está la comunicación entre procesos no relacionada. Por supuesto, los procesos relacionados también pueden comunicarse mediante colas de mensajes.
proto.h
#ifndef PROTP_H_
#define PROTO_H_
#define KEYPATH "/etc/services"
#define KEYPROJ 'g'
#define NAMESIZE 32
struct msg_st
{
long mtype;// 仿照 struct msgbuf
char name[NAMESIZE];
int math;
int chinese;
};
#endif
proceso del receptor rcver.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/msg.h>
#include "proto.h"
int main(void)
{
key_t key;
int msgid;
struct msg_st rbuf;
key = ftok(KEYPATH,KEYPROJ);//获取IPC 键值
if(key < 0)
{
perror("ftok");
exit(1);
}
msgid = msgget(key,IPC_CREAT|0600); //创建 消息队列 返回IP
if(msgid < 0)
{
perror("msgget");
exit(1);
}
while(1)
{
//从目标消息队列 接受数据,注意接收数据的大小是有效数据的大小
if(msgrcv(msgid,&rbuf,sizeof(rbuf)-sizeof(long),0,0) < 0)
{
perror("msgrcv");
exit(1);
}
printf("NAME = %s\n",rbuf.name);
printf("MATH = %d\n",rbuf.math);
printf("CHINESE = %s\n",rbuf.chinese);
}
msgctl(msgid,IPC_RMID,NULL);//销毁消息队列
exit(0);
}
proceso del remitente snder.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <string.h>
#include "proto.h"
int main()
{
key_t key;
int msgid;
struct msg_st sbuf;
key = ftok(KEYPATH,KEYPROJ);//获取消息队列 IPC 键值
if(key < 0)
{
perror("ftok");
exit(1);
}
msgid = msgget(key,0);//获得已创建好的目标消息队列 的 ID
if(msgid < 0)
{
perror("msgget");
exit(1);
}
//初始化数据
sbuf.mtype = 1;
strcpy(sbuf.name,"MHR");
sbuf.math = rand()%100;
sbuf.chinese = rand()%100;
// 发送数据
if(msgsnd(msgid,&sbuf,sizeof(sbuf)-sizeof(sbuf),0) < 0)
{
perror("msgsnd");
exit(1);
}
puts("OK");
exit(0);
}
Cabe señalar que si el proceso del remitente se ejecuta primero 10 veces, y luego el proceso del receptor se ejecuta nuevamente, el receptor aceptará los datos enviados por el remitente 10 veces antes. Esto se debe a que la
cola de mensajes tiene la capacidad de almacenar mensajes en caché, cuántos datos se pueden almacenar en caché, se pueden ver con ulimit -a
mhr@ubuntu:~/Desktop/xitongbiancheng/communication/msg/basic$ ulimit -a
...
POSIX message queues (bytes, -q) 819200
...
mhr@ubuntu:~/Desktop/xitongbiancheng/communication/msg/basic$
ipcs ver IPC actual
ipcrm: ipcrm-remove ciertos recursos de IPC eliminan los parámetros de IPC especificados en el siguiente
Como eliminar la cola de mensajes especificada:
Primero verifique el ID de la cola de mensajes de destino
mhr @ ubuntu: ~ / Desktop / xitongbiancheng / communication / msg / basic $ ipcs
------ Message Queues --------
key msqid owner perms used-bytes messages
0x670100d2 0 mhr 600 0 0
…
Eliminar:
mhr @ ubuntu: ~ / Desktop / xitongbiancheng / communication / msg / basic $ ipcrm -q 0
OPCIONES
-M, --shmem-key shmkey
Remove the shared memory segment created with shmkey after the last detach is performed.
-m, --shmem-id shmid
Remove the shared memory segment identified by shmid after the last detach is performed.
-Q, --queue-key msgkey
Remove the message queue created with msgkey.
-q, --queue-id msgid
Remove the message queue identified by msgid.
-S, --semaphore-key semkey
Remove the semaphore created with semkey.
-s, --semaphore-id semid
Remove the semaphore identified by semid.
-V, --version
Display version information and exit.
-h, --help
Display help text and exit.