linux进程间通信-消息队列

2021-03-14

简介

消息队列是消息的链接表 ,存放在内核中并由消息队列标识符标识。我们将称消息队列为“队列”,其标识符为“队列ID”。 msgget用于创建一个新队列或打开一个现存的队列。 msgsnd用于将新消息添加到队列尾端。每个消息包含一个正长整型类型字段,一个非负长度以及实际数据字节(对应于长度),所有这些都在将消息添加到队列时,传送给msgsndmsgrcv用于从队列中取消息。我们并不一定要以先进先出次序取消息,也可以按消息的类型字段取消息。

函数介绍

ftok

生成一个key(键值)

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

key_t ftok(const char *pathname, int proj_id);

msgget

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

int msgget(key_t key, int msgflg);

功能:创建或取得一个消息队列对象 返回:消息队列对象的id 同一个key得到同一个对象 格式:msgget(key,flag|mode); flag:可以是0或者IPC_CREAT(不存在就创建) mode:同文件权限一样

msgsnd

将msgp消息写入标识为msgid的消息队列

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

返回值:

msgrcv

从标识符为msgid的消息队列里接收一个指定类型的消息 并 存储于msgp中 读取后 把消息从消息队列中删除

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
int msgflg);

参数:

msgctl

int msgctl(int msqid, int cmd, struct msqid_ds *buf);
msgctl(msgid,IPC_RMIDNULL);//删除消息队列对象

示例

// snd.c
#include <stdio.h>    
#include <sys/types.h>
#include <sys/ipc.h>  
#include <sys/msg.h>  
#include <error.h>    
#include <stdlib.h>   
#include <fcntl.h>    

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

int main()
{
    key_t key = ftok("./ftok_kk",'6');
    printf("key:%x\n",key);

    int msgid = msgget(key,IPC_CREAT|O_WRONLY|0777);
    if(msgid<0)
    {   
        perror("msgget error!");
        exit(-1);
    }   

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

    return 0;
}
// rcv.c
#include <stdio.h>    
#include <sys/types.h>
#include <sys/ipc.h>  
#include <sys/msg.h>  
#include <error.h>    
#include <stdlib.h>   
#include <fcntl.h>
 
typedef struct{
    long type;
    char name[20];
    int age;
}Msg;

int main()
{
    key_t key = ftok("./ftok_kk",'6');
    printf("key:%x\n",key);

    int msgid = msgget(key,O_RDONLY);
    if(msgid<0)
    {   
        perror("msgget error!");
        exit(-1);
    }   

    Msg rcv;
    long type;
    puts("please input type you want!");
    scanf("%ld",&type);

    msgrcv(msgid,&rcv,sizeof(rcv)-sizeof(type),type,0);
    printf("rcv--name:%s age:%d\n",rcv.name,rcv.age);

    msgctl(msgid,IPC_RMID,NULL);
    return 0;
}
$ ./snd
key:36012dbf
please input your type name age:
3
1
2

$ ./rcv
key:36012dbf
please input type you want!
3
rcv--name:1 age:2

其它

ipcs -q 查看消息队列

参考: https://www.cnblogs.com/liudw-0215/p/8978945.html

words: 1072 tags: linux进程间通信