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.