在嵌入式Linux应用开发中,Linux进程通信的方式有6种,分别是管道(pipe)及有名管道(named pipe)、信号(signal)、消息队列(msg)、共享内存(shm)、信号量、和套接字(socket),在这我就简单的描述一下进程通信中的信息队列(msg):
首先,消息队列的实现有重要的几步:
1、创建或打开消息队列;
int msgget(key_t key,int flag)
——key :代表返回新的或已有队列的队列ID,IPC_PRIVATE,可通过ftok生成
——返回值(int flag):消息队列ID(msqid)
2、添加信息;
int msgsnd(int msgqid,const void *prt,size_t size,int flag)
——其中prt指的是指向消息队列结构的指针,消息队列结构体:
struct msgbuf
{
long mtype;
char mtext[1];
}
3、读取信息;
int msgrcv(int msgqid,struct msgbuf *msgp,int size,long msgtype,int flag)
——其中msgtype等于零:接收消息对列中的第一个消息
大于零:接收消息队列中第一个类型为没事干type的消息
小于零:接收消息队列中第一个类型值不小于msgtype绝对值且类型值又最小的消息
——在flag:如果flag=MSG_NOERROR,代表若返回的消息比size字节多,则消息就会截短到size字节,且不通知消息发送进程
如果flag=IPC_NOWAIT,代表若消息并没有立即发送而调用进程会立即返回
如果flag=0,代表msgsnd调用阻塞直到条件满足为止
4、控制消息队列。
int msgctl(int msgqid,int cmd,struct msqid_ds *buf)
——其中如果cmd=IPC_STAT:代表读取消息队列的数据结构msgqid_ds,并将其存储在buf指定的地址中
如果cmd=IPC_SET:代表设置消息队列的数据结构msgqid_ds中的ipc_perm元素的值。这个值取自buf参数
如果IPC_RMID:从系统内核中移走消息队列
下面是一个简单的代码:
#include
#include
#include
#include
#include
#include
#include
#define BUFSZ 512
struct message
{
long msg_type;
char msg_text[BUFSZ];
};
int main()
{
int qid; //定义一个qip符号
key_t key;//定义一个key
int len;//类型是len
struct message msg;//消息队列的结构体
if((key=ftok(".",'a'))==-1){//通过ftok判断有没有返回新的或已有的队列的ID
perror("ftok");
exit(1);
}
if((qid=msgget(key,IPC_CREAT|0666))==-1){//创建一个权限为读写的消息对列
perror("msgget");
exit(1);
}
printf("opened queue %d
",qid);
puts("Please enter the message to queue:");
if((fgets((&msg)->msg_text,BUFSZ,stdin))==NULL){
puts("no message");
exit(1);
}
msg.msg_type = getpid();
len = strlen(msg.msg_text);
if((msgsnd(qid,&msg,len,0))<0){//判断有没有添加消息
perror("message posted");
exit(1);
}
if(msgrcv(qid,&msg,BUFSZ,0,0)<0){//判断有没有消息读
perror("msgrcv");
exit(1);
}
printf("message is:%s
",(&msg)->msg_text);
if((msgctl(qid,IPC_RMID,NULL))<0){
perror("msgctl");
exit(1);
}
exit(0);
}