进程通信IPC----消息队列教程

2020-03-06 10:04:08
  1. 往消息队列中发送消息,消息的类型如结构体Msg所示:
#include<sys/types.h>
#include <sys/msg.h>
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>

typedef struct 
{
    long type;
    char name[20];
    int age;
}Msg;

int main(int argc, char const *argv[])
{
    key_t key = ftok("/home/test/msgq",'8');
    int msgid = msgget(key, IPC_CREAT|O_WRONLY|0777);
    printf("send-key:%x , msgid:%d\n",key,msgid);
    if (msgid < 0)
    {
        perror("msgget error!");
        exit(-1);
    }
    Msg m;
    while(1){
         memset(&m,0,sizeof(m));
         puts("please input your type name age:");
         scanf("%ld%s%d",&m.type, m.name,&m.age);
         msgsnd(msgid, &m,sizeof(m) - sizeof(m.type),0);
    }
    msgctl(msgid,IPC_RMID,NULL);
    return 0;
}
  1. 从消息队列中读取数据
#include<sys/types.h>
#include <sys/msg.h>
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>

typedef struct{
    long type;
    char name[20];
    int age;
}Msg;

int main(int argc, char const *argv[])
{
    //该路径可以随便设置,但是发送接收两端保持一致即可
    //该路径是必须存在的,ftok只是根据文件inode在系统内的唯一性来取一个数值,和文件的权限无关。
    //proj_id是可以根据自己的约定,随意设置。这个数字,有的称之为project ID; 在UNIX系统上,它的取值是1到255
    key_t key = ftok("/home/test/msgq",'8');
    int msgid = msgget(key,O_RDONLY);
    printf("read-key:%x , msgid:%d\n",key,msgid);
    if(msgid<0)
    {   
        perror("msgget error!");
        exit(-1);
    }
    Msg rcv;
    long type;
    ssize_t result = 0;
    while(1){
        memset(&rcv, 0, sizeof(rcv));
        puts("please input type you want!");
        scanf("%ld",&type);
        result = msgrcv(msgid,&rcv, sizeof(rcv) - sizeof(type), type, IPC_NOWAIT);
        printf("result=:%d\n", result );
        //读取不到,立马返回,返回-1,不会一直阻塞. 
        //如果把 IPC_NOWAIT改成0,msgrcv会一直阻塞,知道队列中有该条消息才往下执行
        if (result == -1)
        {
            printf("there is no msg what you want, pls check again\n");
            continue;
        }
        printf("rcv--name:%s age:%d\n",rcv.name,rcv.age);
    }
    msgctl(msgid,IPC_RMID,NULL);

    return 0;
}

A: 如下截图往消息队列中发送了3条消息

B: 然后从消息队列中可以根据消息类型读取(可以指定消息类型读取,没有顺序,每条消息只能读取一次,重复读取或者读取不存在的消息msgrcv(最后一个参数设定为IPC\_NOWAIT)将会返回-1)

C: 通过ipcs 查看消息队列,其中key和msgid跟代码打印的log保持一致.

D: 如果此时此时 ipcrm -q 1048576 或者 ipcrm -Q 0xffffffff ,则内核队列会删除,此时再次运行对应的程序,由于两者之间建立的消息通道已经被删除,所以无法再次建立通信了

E: 经测试发现ftok第一个参数: 该文件路径/home/test/msgq 不一定真实存在,但是发送端和接收端必须保持一致.

当前页面是本站的「Baidu MIP」版。发表评论请点击:完整版 »