Programación del sistema Linux 64 procesos, comunicación entre subprocesos, cola de 2 mensajes

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:

Inserte la descripción de la imagen aquí

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.

Supongo que te gusta

Origin blog.csdn.net/LinuxArmbiggod/article/details/114849370
Recomendado
Clasificación