msgget(message get)
msgctl (message contorl)
msgsnd (message send)
msgrcv (message receive)
(1)msgget(创建消息队列)
所需头文件 | #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> |
函数原型 | int msgget(key_t key,int flag); |
函数参数 | key:和消息队列关联的key值 |
flag:消息队列的访问权限 | |
函数返回值 | 成功:消息队列ID |
失败:-1 |
创建一个消息队列:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <signal.h>
#include <unistd.h>
int main()
{
int msgid;
msgid=msgget(IPC_PRIVATE,0777);
if(msgid<0)
{
printf("creat message queue failure\n");
return -1;
}
printf("creat message queue sucess msgid=%d\n",msgid);
system("ipcs -q");
return 0;
}
执行结果如下:
key值为0,因为是通过IPC_PRIVATE的值来创建的。
(2)msgctl
所需头文件 | #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> | |
函数原型 | int msgctl(int msgqid,int cmd,struct msqid_ds *buf); | |
函数参数 | msgqid:消息队列的队列ID | |
cmd | IPC_STAT:读取消息队列的属性,并将其保存在buf指向的缓冲区中 | |
IPC_SET:设置消息队列的属性。这个值取自buf参数 | ||
IPC_RMID:从系统中删除消息队列 | ||
buf:消息队列缓冲区 | ||
函数返回值 | 成功:0 | |
失败:-1 |
msgctl函数的使用例程
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <signal.h>
#include <unistd.h>
int main()
{
int msgid;
msgid=msgget(IPC_PRIVATE,0777);
if(msgid<0)
{
printf("creat message queue failure\n");
return -1;
}
printf("creat message queue sucess msgid=%d\n",msgid);
system("ipcs -q");
//delete message queue
msgctl(msgid,IPC_RMID,NULL);
system("ipcs -q");
return 0;
}
执行结果如下:
(3)msgsnd函数
所需头文件 | #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> |
函数原型 | int msgsnd(int msqid,const void *msgp,size_t size,int flag); |
函数参数 | msqid:消息队列id |
msgp:指向消息的指针。常用消息结构msgbuf如下: struct msgbuf { long mtype; //消息类型 char mtext[N]; //消息正文 }; | |
size:发送消息正文的字节数 | |
flag:IPC_NOWAIT 消息没有发送完成函数也会立即返回。(非阻塞) 0:直到发送完成函数才返回(阻塞) | |
函数返回值 | 成功:0 |
失败:-1 |
(4)msgrcv
所需头文件 | #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> | |
函数原型 | int msgrcv(int msgid,void *msgp,size_t size,long msgtype,int flag); | |
函数参数 | msgid:消息队列的ID | |
msgp:接收消息的缓冲区 | ||
size:要接收的消息的字节 | ||
msgtype | 0:接收消息队列中第一个消息 | |
大于0:接收消息队列中第一个类型为msgtyp的消息 | ||
小于0:接收消息队列中类型值不大于msgtyp的绝对值且类型值又最小的消息 | ||
flag | 0:若无消息函数会一直阻塞 | |
IPC_NOWAIT(非阻塞):若无消息 ,进程会立即返回ENOMSG。 | ||
函数返回值 | 成功:接收到的消息的长度 | |
出错:-1 |
消息队列读完节点数据会被删除
#include <stdlib.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
struct msgbuf
{
long type;
char text[124];
char ID[4];
};
int main()
{
int msgid;
int readret;
struct msgbuf sendbuf,recvbuf;
msgid=msgget(IPC_PRIVATE,0777);
if(msgid<0)
{
printf("creat message queue failure\n");
return -1;
}
printf("creat message queue sucess msgid=%d\n",msgid);
system("ipcs -q");
//init sendbuf
sendbuf.type=100;
printf("please input message:\n");
fgets(sendbuf.text,124,stdin);
//start wirte message to message queue
msgsnd(msgid,(void *)&sendbuf,strlen(sendbuf.text),0);
//start read message from message queue
memset(recvbuf.text,0,124);
readret=msgrcv(msgid,(void *)&recvbuf,124,100,0);
printf("recv:%s",recvbuf.text);
printf("readret=%d\n",readret);
//second read message queue
msgrcv(msgid,(void *)&recvbuf,124,100,0);
printf("second read after\n");
//delete message queue
msgctl(msgid,IPC_RMID,NULL);
system("ipcs -q");
return 0;
}
执行结果如下:
例程:实现消息队列的双向通信
服务器程序
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
struct msgbuf
{
long type;
char text[124];
char ID[4];
};
int main()
{
int msgid;
int readret;
int key;
pid_t pid;
struct msgbuf sendbuf,recvbuf;
key=ftok("./b.c",'a');
if(key<0)
{
printf("creat key failure\n");
}
msgid=msgget(key,IPC_CREAT|0777);
if(msgid<0)
{
printf("creat message queue failure\n");
return -1;
}
printf("creat message queue sucess msgid=%d\n",msgid);
system("ipcs -q");
pid=fork();
if(pid>0)//father process write 100
{
sendbuf.type=100;
//WRITE MESSAGE QUEUE
while(1)
{
memset(sendbuf.text,0,124);
printf("please input message:\n");
fgets(sendbuf.text,124,stdin);
msgsnd(msgid,(void *)&sendbuf,strlen(sendbuf.text),0);
}
}
if(pid==0)//son process
{
while(1)
{
memset(recvbuf.text,0,124);
msgrcv(msgid,(void *)&recvbuf,124,200,0);
printf("receive message form message queue:%s\n",recvbuf.text);
}
}
msgctl(msgid,IPC_RMID,NULL);
system("ipcs -q");
return 0;
}
客户端程序
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
struct msgbuf
{
long type;
char text[124];
char ID[4];
};
int main()
{
int msgid;
int readret;
int key;
pid_t pid;
struct msgbuf sendbuf,recvbuf;
key=ftok("./b.c",'a');
if(key<0)
{
printf("creat key failure\n");
}
msgid=msgget(key,IPC_CREAT|0777);
if(msgid<0)
{
printf("creat message queue failure\n");
return -1;
}
printf("creat message queue sucess msgid=%d\n",msgid);
system("ipcs -q");
pid=fork();
if(pid==0)//son process write 100
{
sendbuf.type=200;
//WRITE MESSAGE QUEUE
while(1)
{
memset(sendbuf.text,0,124);
printf("please input message:\n");
fgets(sendbuf.text,124,stdin);
msgsnd(msgid,(void *)&sendbuf,strlen(sendbuf.text),0);
}
}
if(pid>0)//father process read 100
{
while(1)
{
memset(recvbuf.text,0,124);
msgrcv(msgid,(void *)&recvbuf,124,100,0);
printf("receive message form message queue:%s\n",recvbuf.text);
}
}
msgctl(msgid,IPC_RMID,NULL);
system("ipcs -q");
return 0;
}
执行结果如下: