您的位置:首页 > 运维架构 > Linux

linux 消息队列实例讲解

2013-03-25 17:39 411 查看
在做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绝对值的第一条消息。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: