转载:http://blog.sina.com.cn/u/2312748742
现在linux使用的进程间通信有:管道,信号,消息队列,共享内存,信号量,套接字。
linux下ipc信息查看: ipcs
一、消息队列提供了一个从一个进程向另一个进程发送一块数据的方法。
二、可分system v系列函数和posix系列函数(可以用于window下,必须加入包);
三、system v函数如下:
1)头文件 #include<sys/msg.h> #include<sys/types.h> #include<sys/ipc.h>
//创建一个消息队列,key为消息队列唯一id
2)int msgget(key_t key,int msgflg);
3)msgsnd(int msqid,struct msgbuf*msgp,size_t msgsz,int msgflg);
//msg_typ为接收的类型,msgtype=0 返回队列里的第一个信息
//msgtype>0 返回队列里第一个类型一样的信息
//msgtype<0 返回队列里第一条<=类型的绝对值的消息。
//msgflg=IPC_NOWAIT 队列没有可读消息则不等待。返回ENOMSG错误
//msgflg=MSG_NOERROR 消息大于msgsz时超过的被截断
//msgtype>0且msgflg=MSC_EXCEPT接收类型不等于msgtype的第一条信息
4)msgrcv(int msqid,struct msgbuf*msgp,size_t msgsz,long msg_typ,
msg_typ,int msgflg);
//command将要采取的动作,IPC_STAT获取当前消息值储存在msqid_ds结构中
//IPC_SET //IPC_RMID 直接删除消息队列
5)int msgctl(int msqid,int command,struct msqid_ds *buf);
例子:
#include<sys/msg.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include <unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>
#include<signal.h>
#include<string.h>
#define ERR_INFO(info)\
do\
{ \
perror(info);\
exit(EXIT_FAILURE);\
}while(0); //与分好结束
#define MAX_SIZE 100
struct msgbuf0 //库里也有但是长度只有1太小了。
{
long mtype; //类型
char mtext[MAX_SIZE];
};
int main(int argc, char *argv[]) //argc 有几个参数 编译执行时
{
if(argc<4)
{
ERR_INFO("params error\n!");
}
int msgID=msgget((key_t)111,IPC_CREAT|0777);//创建一个消息队列操作成功返回一个标识码非负数否则-1 返回的是队列码
if(msgID==-1)
{
ERR_INFO("msgget error!\n");
}
else //创建成功
{
struct msgbuf0 Mymsg;
memset(&Mymsg,0x00,sizeof(struct msgbuf0 ));
if(strncmp(argv[1],"send",4)==0) //发送
{
Mymsg.mtype=atoi(argv[2]);
strcpy(Mymsg.mtext,argv[3]);
int rlt=msgsnd(msgID,&Mymsg,MAX_SIZE,IPC_NOWAIT); //添加到消息队列里去 最后一个参数 队列不等待
if(rlt==-1)
{
ERR_INFO("msgsnd error!\n");
}
printf("msgsnd: %s\n",Mymsg.mtext);
}
else if (strncmp(argv[1],"recv",4)==0) //接收
{
int rlt=msgrcv(msgID,&Mymsg,MAX_SIZE,atoi(argv[2]),IPC_NOWAIT); //接收
if( rlt==-1)
{
ERR_INFO("msgrcv error!\n");
}
printf("msgrcv :%s\n",Mymsg.mtext);
}
}
struct msqid_ds msgHeadinfo; //存放队列的信息 在man msgctl中
memset(&msgHeadinfo,0x00,sizeof(struct msqid_ds));
msgctl(msgID,IPC_STAT,&msgHeadinfo); //存储当队列的信息
if(msgHeadinfo.msg_qnum==0) // 队列的消息个数
{
msgctl(msgID,IPC_RMID,NULL); //删除队列
printf("delete msg_queue,msgID= %d\n",msgID);
}
else
{
printf("msgID :%d not delete...\n",msgID);
}
return 0;
}
//执行 g++ msg.cpp -o main
运行 ./main send 100 hello
在运行./main recv 100 0
用ipcs可以看到消息队列
注意:int main(int argc,char *argv[])里面函数的含义如下:
int argc, char **argv 用于运行时,把命令行参数传入主程序。
argc -- 命令行参数 总个数,包括 可执行程序名。
argv[i] -- 第 i 个参数。
argv[0] -- 可执行程序名。
例如运行:
abc.exe
argc 等于 1, argv[0] 是 "abc.exe"
例如运行:
rec.exe 4 5.2
argc 等于 3, argv[0] 是 "rec.exe", argv[1] 是 "4", argv[2] 是 "5.2".