linux 消息队列实例讲解

       在做linux多任务编程的时候,难免会碰到要使用IPC技术了,但是很多人都对这些技术只知其名,不知道如何使用。为了大家都能很好的学习Linux,本人不才,贴出了自己写的 消息队列 编程,用的是多线程,不是多进程,原理一样。以后有时间会后续把其他几个技术一一详解,并贴上代码。好了,废话不多说,进入下面的实例讲解。

/*****************************************************

**头文件包含

****************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>  //ftok, msgget, msgrcv, msgsnd
#include <sys/ipc.h>   //ftok, msgget, msgrcv, msgsnd
#include <sys/msg.h> //ftok, msgget, msgrcv, msgsnd
#include <pthread.h> //多线程
#include <string.h> //memcpy
#include <unistd.h>
#define KEYFILE "/root/work/msgqueue"  //产生系统唯一的键值所用,这个目录或文件一定要存在
#define PROJID 10  //产生系统唯一的键值项目号。


struct msg{

 long type;  //消息类型
 char buf[512]; //消息内容
};

/*******************************************************

**创建系统唯一的键值,为msgget所用,也可以不

**用调用此函数,用一个常数代替key,但是为避免

**创建的消息队列失败,建议用此方法。

*******************************************************/

key_t CreateMsgKey()
{
 return ftok(KEYFILE,PROJID);//系统调用,返回一个系统唯一的键值。

}

/********************************************************

**下面是创建一个线程,并设置为分离态,这个应该

**就不需要多说了吧。

*********************************************************/
pthread_t createthread(void* (*fun)(void *),void *arg)
{
 pthread_t threadId;
 pthread_attr_t attr;
 memset(&attr,0,sizeof(attr));
 pthread_attr_init(&attr);
 pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
 return  pthread_create(&threadId,&attr,fun,arg);

}

/*******************************************

**待会要创建的线程工作函数,此线程

**每隔2秒向消息队列里发一条消息。

********************************************/
void *DoSndMsg(void *arg)
{
 struct msg SndMsg;
 long iCount=1;
 SndMsg.type=100;//消息类型为100
 int msgid=0;
 msgid=msgget(*(key_t *)arg,IPC_CREAT);//获取消息队列的ID,arg是由进程传进来的key,IPC_CREAT表示创建一个新的

                                                                           //消息队列,如果,如果key已经创建了消息队列,则返回已经创建的消息队列ID。

                                                                            //如果IPC_EXCL | IPC_CREAT一起用,如果key已经创建了消息队列,则返回错误。
 printf("msgid is:%d\n",msgid);  //打印下msgid
 while(iCount>0)
 {
  iCount+=1;;
  memcpy(SndMsg.buf,&iCount,sizeof(iCount));
  msgsnd(msgid,&SndMsg,sizeof(SndMsg),IPC_NOWAIT);//把sndmsg里的消息发送到msgid的消息队列里,IPC_NOWAIT表示

                                                                                                      //不阻 塞。
  printf("iCount is:%ld\n",iCount);
  sleep(2);
 }
 return NULL;
}
int main()
{
 pthread_t sndThread;
 struct msg rcvMsg;
 int msgid;
 long rcvCount=0;
 key_t msgkey;
 msgkey=CreateMsgKey(); //创建key

 sndThread=createthread(DoSndMsg,&msgkey);//创建线程。
 msgid=msgget(msgkey,IPC_CREAT);//获取消息队列ID
 printf("msgid is:%d\n",msgid);
 while(rcvCount==0)
 {
  msgrcv(msgid,&rcvMsg,sizeof(rcvMsg),0,IPC_NOWAIT);//接收msgid里第一条消息,0的位置是消息类型,
0,表示消息队列

                                                                                                   //第一条消息,大于零的值则表示收取相应消息类型的消息。
  memcpy(&rcvCount,rcvMsg.buf,sizeof(rcvCount));
  printf("msgtype:%ld\n",rcvMsg.type);
  printf("rcvCount is:%ld\n",rcvCount);
  sleep(2);
  rcvCount=0;

 }

 return EXIT_SUCCESS;
}
          系统调用msgrcv中的参数type非常的重要,这个形参决定读取消息队列中哪一条消息,unix环境高级编程里做了很好的总结,现在分享给大家。

          type==0, 表示读取消息队列中的第一条消息(任何类型的消息都接收);

          type>0,   表示读取消息队列中类型为type的第一条消息(如果有多条同类型消息,一次只读最前面的一条消息);

          type<0,   表示读取消息队列中类型为小于或者大于type绝对值的第一条消息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值