进程间通信——消息队列

xiaoxiao2021-02-28  95

什么是消息队列? 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。  每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构。我们可以通过发送消息来避免命名管道的同步和阻塞问题。但是消息队列与命名管道一样,每个数据块都有一个最大长度的限制。 查看系统中ipc的数量:ipcs     -m      shared memory segments 查看共享内存情况     -q      message queues         查看消息队列情况     -s      semaphores             查看信号量     -a      all (default) 1.创建秘钥函数 头文件:      #include <sys.types.h>     #include <sys/ipc.h> 函数原型:     key_t ftok(const char *pathname,int proj_id); 参数一:路径名 参数二:秘钥ID,是一个8bit的整型 返回值:成功返回一把秘钥,失败返回-1 2.创建消息队列ipc对象 头文件:     #include <sys/types.h>     #include <sys/ipc.h>     #include <sys/msg.h> 函数原型:     int msgget(key_t key,int msgflg); 参数一:创建消息队列的一个秘钥,必须是唯一的 参数二:IPC_CREAT   ---》创建ipc对象          O_EXCL ---》检查ipc对象是否存在,存在则创建失败          0666  ---》权限,不能忘了 返回值:成功返回一个ipc对象id,失败返回-1 3.发送信息 msgsnd() 函数原型; int msgsnd(int msqid, -》IPC对象ID        const void *msgp, -》要发送的消息  该指针指向这个结构体 struct msgbuf {                              long mtype;    -》发送的消息类型,自己定义一个唯一的整形即可            char mtext[1]; -》数据缓存区             };        size_t msgsz,  -》有效数据的大小  mtext里面的有效数据         int msgflg); -》发送标志   IPC_NOWAIT  -》不阻塞                0       -》阻塞 (但是发送一般不阻塞,除非队列已满) 4.接收信息 msgrcv() 函数原型:  ssize_t msgrcv(int msqid,-》IPC对象ID           void *msgp,  -》数据缓存区 他需要这样的结构体保存数据  struct msgbuf {                 long mtype;    -》发送的消息类型,自己定义一个唯一的整形即可             char mtext[1]; -》数据缓存区            }; size_t msgsz, -》要接收数据的大小 ,(按实际数据的大小接收)           long msgtyp, -》重点(指定的接收类型,在发送函数中定义好的类型)      0  接收任何信息         int msgflg);-》接收标志          IPC_NOWAIT  -》不阻塞 0          -》阻塞  5. msgctl函数 该函数用来控制消息队列,它与共享内存的shmctl函数相似, 函数原型: int msgctl(int msgid,int command,struct msgid_ds *buf); 参数一:msgid是由msgget函数返回的消息队列标识符。 参数二: command是将要采取的动作,它可以取3个值,     IPC_STAT:把msgid_ds结构中的数据设置为消息队列的当前关联值,即用消息队列的当前关联值覆盖msgid_ds的值。     IPC_SET:如果进程有足够的权限,就把消息列队的当前关联值设置为msgid_ds结构中给出的值     IPC_RMID:删除消息队列 参数三:buf是指向msgid_ds结构的指针,它指向消息队列模式和访问权限的结构。msgid_ds结构至少包括以下成员: struct msgid_ds   {       uid_t shm_perm.uid;       uid_t shm_perm.gid;       mode_t shm_perm.mode;   };   -------------------------------------------------------------------------------------------------- 示例程序: 发送信息部分: #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <string.h> int main() { //创建一把秘钥 key_t key=ftok("/",120); //创建消息队列的IPC对象 int msgid=msgget(key,IPC_CREAT|0666); if(msgid != -1) { printf("creat msgget ok\n"); } //发送数据 struct msgbuf { long mtype; char mtext[100]; }; struct msgbuf sendbuf; sendbuf.mtype =500;//500类型的数据 // sendbuf.mtext = "123456"; 错误 strcpy(sendbuf.mtext,"123456"); msgsnd(msgid,&sendbuf,6,0); //删除消息队列 int ret=msgctl(msgid,IPC_RMID,NULL); if(ret == 0) { printf("ret=%d\n",ret); } else { perror("rmid:"); } } 接收信息部分: #include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <string.h> int main() { //创建一把秘钥 key_t key=ftok("/",120); //创建消息队列的IPC对象 int msgid=msgget(key,IPC_CREAT|0666); if(msgid != -1) { printf("creat msgget ok\n"); } //接收数据 struct msgbuf { long mtype; char mtext[100]; }; struct msgbuf recv; bzero(recv.mtext,100);//别忘了每次接收前要清空缓冲区 msgrcv(msgid,&recv,6,500,0);//接收500类型的数据 printf("recv=%s\n",recv.mtext); }
转载请注明原文地址: https://www.6miu.com/read-40435.html

最新回复(0)