消息队列:
1》创建新消息队列或取得已存在消息队列---msgget
#include <sys / types.h>
#include <sys / ipc.h>
#include <sys / msg.h>
int msgget(key_t key, int msgflg);
参数
key:键值。
msgflg:IPC_CREAT|0666值,若没有该队列,则创建一个并返回新标识符;若已存在,则返回原标识符。
返回值:成功执行时,返回消息队列标识值。失败返回-1;
eg:
int key=ftok();
int msgid=msgget(key,IPC_CREAT);
if(msgid==-1)
{
perror(msgget);
return -1;
}
2》添加消息队列(发送)---msgsnd
把消息添加到已打开的消息队列末尾
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
参数
msgid:指明消息队列的 ID,通常是 msgget 函数成功的返回值
msgp:发送数据缓冲区首地址
msgp:指向消息结构的指针。该消息结构 msgbuf 为:
struct msgbuf{
long mtype;//消息类型
char mtext[1];//消息正文 可以任意类型
}
msgsz:要发送的数据大小,上一个参数的大小减去sizeof(long),每个消息体最大不要超过
msgflg:一般赋0,阻塞方式;
返回值:成功则返回0, 出错则返回-1
struct msgbuf{
long type;
char buf[32];
};
struct msgbuf s = {111,”liming”}
msgsnd(msgid,&s,)
3》读取消息(接收) ---msgrcv
把消息从消息队列中取走,与 FIFO不同的是,这里可以指定取走某种type的消息
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
参数
msqid:消息队列的队列
msgp:消息缓冲区
size:消息的字节数
msgtyp:消息类型
=0 忽略类型
>0 只接收指定类型的数据
<0 只接受小于等于其绝对值的数据
msgflg:0 -- 阻塞
返回值
接收成功返回0,失败返回-1
4》控制消息队列-- msgctl
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
参数
msqid:消息队列的队列
cmd
IPC_STAT:读取消息队列的数据结构 msqid_ds,并将其存储在buf 指定的地址中
IPC_SET:设置消息队列的数据结构 msqid_ds 中的 ipc_perm 元素的值。这个值取自 buf 参数
IPC_RMID:从系统内核中删除消息队列,最后一个参数填写NULL;
Buf:消息队列缓冲区
返回值
接收成功返回0,失败返回-1
例题:实现收发打印出来(创建fork)
//--------------------------发
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msgbuf{
long type;//消息类型
char name[16];//消息正文 可以任意类型
};
int main()
{
int key=ftok("/home/fuc/test/2_23",11);
int msgid=msgget(key,IPC_CREAT|0666);//创建消息队列
struct msgbuf m1={111,"小红"};
struct msgbuf m2={111,"奥德彪"};
struct msgbuf m3={222,"翠芬"};
//写入消息队列
msgsnd(msgid,&m1,sizeof(m1)-sizeof(long),0);
msgsnd(msgid,&m2,sizeof(m2)-sizeof(long),0);
msgsnd(msgid,&m3,sizeof(m3)-sizeof(long),0);
return 0;
}
//--------------------------收
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <errno.h>
#include <wait.h>
struct msgbuf{
long type;//消息类型
char name[16];//消息正文 可以任意类型
};
int main()
{
int key=ftok("/home/fuc/test/2_23",11);
int msgid=msgget(key,IPC_CREAT|0666);//打开消息队列
//写入消息队列
struct msgbuf m1;
pid_t pid=fork();
if(pid>0)
{
while(1)
{
wait(NULL);
int a=msgrcv(msgid,&m1,sizeof(m1)-sizeof(long),111,IPC_NOWAIT);
if((a==-1)&&(errno==ENOMSG))
{
break;
}
printf("father:%s\n",m1.name);
}
}
if(pid==0)
{
while(1)
{
int a=msgrcv(msgid,&m1,sizeof(m1)-sizeof(long),222,IPC_NOWAIT);
if((a==-1)&&(errno==ENOMSG))
{
break;
}
printf("son:%s\n",m1.name);
}
}
return 0;
}