Linuxシステムプログラミング64プロセス、スレッド間通信2メッセージキュー

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  

キー値について:

ここに画像の説明を挿入

キー:ftok()、IPCキー値を生成し、パス名とプロジェクト識別子をSystem VIPCキーに変換します

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);

パラメータfnameは、指定されたファイル名です。このファイルは存在し、アクセス可能である必要があります。idはサブシーケンス番号で、8ビット整数です。つまり、範囲は0〜255です。関数が正常に実行されると、key_t値が返されます。それ以外の場合は、-1が返されます。一般的なUNIXでは、通常、ファイルのインデックスノードが取り出され、次にサブシーケンス番号が先頭に追加されてkey_tの値が取得されます。

msgget():新しいメッセージキューを作成するか、既存のメッセージキューを取得するために使用されます

NAME
       msgget - get a System V message queue identifier 获取一个消息队列的ID

SYNOPSIS
       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>

/ *
key:メッセージキューのキー値。この関数は、既存のメッセージキューオブジェクトのキーと比較して、メッセージキューオブジェクトが作成されたかどうかを判断します
。msgflg:現在のメッセージキューを作成するための特別な指定

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.

IPC_CREATフラグを単独で使用する場合、msgget()関数は、既存のメッセージキューオブジェクトの識別子または新しく作成されたメッセージキューオブジェクトの識別子を返します。IPC_CREATフラグとIPC_EXCLフラグを一緒に使用すると、msgget()は新しく作成されたメッセージオブジェクトの識別子を返します。メッセージキューオブジェクトがすでに存在する場合は-1を返します。IPC_EXCLフラグ自体にはあまり意味がありませんが、IPC_CREATフラグと一緒に使用して、結果のメッセージキューオブジェクトが、開かれている既存のオブジェクトではなく、新しく作成されたオブジェクトであることを確認できます。

msgsnd()、msgrcv():メッセージキューを送受信します

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():破棄、設定などのメッセージキューを制御します。

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);

実験:プロセス間通信-メッセージキュー、これは無関係のプロセス間通信です。もちろん、関連するプロセスはメッセージキューを使用して通信することもできます。

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

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);
}

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);
	

}

なお、送信側プロセスを最初に10回実行した後、受信側プロセスを再度実行すると、受信側は送信側から送信されたデータを10回前に受け入れます。これは、
メッセージキューメッセージをキャッシュする機能があり、キャッシュできるデータの量を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は現在のIPCを表示します

ipcrm:ipcrm-特定のIPCリソースを削除し、指定したIPCパラメーターを次のパラメーターに削除します

指定されたメッセージキューの削除など:

まず、ターゲットメッセージキューID
mhr @ ubuntu:〜/ Desktop / xitongbiancheng / communication / msg / basic $ ipcs
------メッセージキュー--------
key msqid owner permsused-bytesメッセージ
0x670100d20を確認します。 mhr 600 00

削除:
mhr @ ubuntu:〜/ Desktop / xitongbiancheng / communication / msg / basic $ ipcrm -q 0

オプション

   -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.

おすすめ

転載: blog.csdn.net/LinuxArmbiggod/article/details/114849370