Linux IPC之消息队列

通过ipcs可以查看消息队列
新增头文件
消息队列中消息的新增和删除是对等的,内部维护一个链表,插入一个消息,删除一个消息
管道中的消息是不对等的,可以一个放入一个"hello",再放入一个"hello",最后一次取出
对于多机之间采用消息队列,而不采用管道
进程结束,消息队列依然存在

消息队列中存放的消息类型为自己手动设置的,每个消息为消息队列中的一个结点

消息队列为空时再次读取会卡住


创建消息队列

    5     //创建消息队列
    6     int msgid=msgget(1000,IPC_CREAT|0600);
    7     ERROR_CHECK(msgid,-1,"msgget");  

发送消息

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
//第二个参数是一个结构体 const void *msgp
struct msgbuf {
    long mtype;       /* message type, must be > 0 */
    char mtext[1];    /* message data */
};
//必须要重写这个结构体,第一个参数不能改
//size_t msgsz 为消息体大小(m.mtext的大小)

   14     struct msgbuf m;
   15     m.mtype=1;//消息类型为1
   16     strcpy(m.mtext,"hello");
   17     int ret;
   18     ret=msgsnd(msgid,&m,strlen(m.mtext),0);                                          
   19     ERROR_CHECK(ret,-1,"msgsnd");

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0x000003e8 0          wenrou     600        5            1           
    1 #include 
    2 
✗   3 struct msgbuf{
    4     long mtype;
    5     char mtext[128];                                                                 
    6 };
    7 
    8 
✹   9 int main(int argc,char*argv[])
   10 {
   11     //创建消息队列
   12     int msgid=msgget(1000,IPC_CREAT|0600);
   13     ERROR_CHECK(msgid,-1,"msgget");
   14     struct msgbuf m;
   15     m.mtype=1;//消息类型为1
   16     strcpy(m.mtext,"hello");
   17     int ret;
   18     ret=msgsnd(msgid,&m,strlen(m.mtext),0);
   19     ERROR_CHECK(ret,-1,"msgsnd");
   20 
   21     return 0;
   22 }

//若发送的消息类型为整数,不能再使用strcpy
//结构体中的mtext仍定义为字符数组
struct msgbuf {
    long mtype;       /* message type, must be > 0 */
    char mtext[128];    /* message data */
};

int i=100;
//除了字符串,其他类型都要用 memcpy
memcpy(m.mtext,&i,sizeof(i));
int ret;
ret=msgsnd(msgid,&m,sizeof(i),0);
ERROR_CHECK(ret,-1,"msgsnd");

接收消息

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
                                                    long msgtyp //优先去读取的消息队列中的消息类型,若该参数设置为0,则按照消息队列顺序读取 

    1 #include                             
    2                                              
✗   3 struct msgbuf{                               
    4     long mtype;                              
    5     char mtext[128];                         
    6 };                                           
    7                                              
    8                                              
✹   9 int main(int argc,char*argv[])               
   10 {                                            
   11     //创建消息队列                           
   12     int msgid=msgget(1000,IPC_CREAT|0600);   
   13     ERROR_CHECK(msgid,-1,"msgget");            
   14     struct msgbuf m={0,{0}};//两个成员                                               
   15     //读取消息队列           
   16     int ret;                 
   17     ret=msgrcv(msgid,&m,sizeof(m.mtext),0,0);
   18     ERROR_CHECK(ret,-1,"msgrcv");
   19     printf("m.mtype=%ld,m.mtext=%s\n",m.mtype,m.mtext);
   20     return 0;                
   21 }  
//接收整数
memcpy(&i,m.mtext,sizeof(i));
//或者这样写,先强制类型转换,再解引用
i = *(int *)m.mtext;

删除消息队列

    5     int msgid=msgget(1000,IPC_CREAT|0600);
    6     ERROR_CHECK(msgid,-1,"msgget");
    7     int ret;
    8     ret=msgctl(msgid,IPC_RMID,NULL);                                                 
    9     ERROR_CHECK(ret,-1,"msgctl");
   10     return 0;

使用命令删除消息队列
ipcrm -q msqid

你可能感兴趣的:(Linux IPC之消息队列)