Linux下多任务间通信和同步-消息队列

时间:2022-08-16 08:09:03
消息队列简称为队列.消息队列就是一些消息的列表.用户可以在消息队列中添加消息和读取消息等.从这点上看,消息队列具有一定的FIFO特性,但是它可以实现消息的随机查询,比FIFO具有更大的优势.同时,这些消息又是存在于内核中的,由"队列ID"来标识. 


消息队列的实现包括创建或打开消息队列,添加消息,读取消息和控制消息队列这四种操作:


创建或打开消息队列使用的函数是msgget,这里创建的消息队列的数量会受到系统消息队列数量的限制;
添加消息使用的函数是msgsnd函数,它把消息添加到已打开的消息队列末尾;
读取消息使用的函数是msgrcv,它把消息从消息队列中取走,与FIFO不同的是,这里可以指定取走某一条消息;
控制消息队列使用的函数是msgctl,它可以完成多项功能.
msgget系统调用
该系统调用创建或打开一个消息队列.msgget函数语法:






其中,msgflag可以为:IPC_CREAT,IPC_EXEC,IPC_NOWAIT或者三者的组合.在一下两种情况下,该调用将创建一个新的消息队列:




如果没有消息队列与键值key相对应,并且msgfalg中包含IPC_CREAT标志位;
key参数为IPC_PRIVATE.


msgsnd系统调用
该系统调用行msgid代表的消息队列发送一个消息.msgsnd函数语法:








对于发送消息来说,有意义的msgflag标志位IPC_NOWAIT,指明在消息队列没有足够容纳要发送的消息时,msgsnd是否等待.造成msgsnd等待的条件有两种:




当前消息的大小与当前消息队列中的字节数之和操作了消息队列的总容量;
当前消息队列中的消息数(单位:个)不小于消息队列的总容量(单位:字节数),此时,虽然消息队列中的消息数目很多,但基本上都只有一个字节.


msgsnd解除阻塞的条件有三个:




不满足上述两个,即消息队列中有容纳该消息的空间
msqid代表的消息队列被删除
调用msgsnd的进程被进程打断


msgrcv系统调用
该系统调用从ID为msgid的消息队列中读取一个消息,并把消息存储子啊msgq指向的msgbuf结构中.msgrcv函数语法:




msgrcv解除阻塞的条件有三个:




消息队列中有了满足条件的消息;
msqid代表的消息队列被删除;
调用msgrcv的进程被信号中断.


msgctl系统调用