在我们以前学习过Unix 线程的知识后,我们来学习下Unix消息队列的知识,在文章中,我们主要讲解Unix消息队列的创建的知识,希望对大家对Unix的学习有所帮助。
依据此数据结构进行Unix消息队列的创建,函数为msqueue_create(参数解释:name消息队列名,maxnum消息的最大个数,length单个消息的长度)。
- int msqueue_create( name, maxnum, length )
- char name;
- int maxnum,length;
- {
- int i;
- for ( i=0; i
- if ( msqueue[i]==NULL )break;
- //如果Unix消息队列全部被分配,返回错
- if ( i==MAXQUEUE ) return MQERROR;
- msqueue[i]=malloc(sizeof(mq_attribstruct));
- sprintf( msqueue[i]->name, "%s", name);
- msqueue[i]->maxElements = maxnum;
- msqueue[i]->elementLength = length;
- msqueue[i]->curElementNum = 0;
- msqueue[i]->buff=malloc(maxnum?length);
- //对保护锁进行初始化
- pthread_mutex_init(&&msqueue[i]
- ->mutex_buff, NULL);
- pthread_mutex_init(&&msqueue[i]
- ->mutex_cond, NULL);
- //对线程同步条件变量初始化
- pthread_cond_init(&&msqueue[i]->cond, NULL);
- return i;
- }
应用Unix消息队列进行消息的发送和接收发送消息到Unix消息队列。
Unix消息队列的发送和接收是在不同的线程中进行的。首先介绍发送消息到Unix消息队列的函数:
- int msqueue_send ( id, buff, length )
- int id, length;
- caddr_t buff;
- {
- int pos;
- //消息队列id错,返回错
- if ( id<0 || id >= MAXQUEU ) return MQERROR;
- //消息长度与创建时的长度不符,返回错
- if ( length != msqueue[id]->elementLength ) return MQERROR;
- //消息队列满,不能发送
- if ( msqueue[id]->curElementNum >= msqueue[id]->maxElements )
- return MQERROR;
- //在对消息队列缓冲区操作前,锁住缓冲区,以免其他线程操作
- pthread_mutex_lock ( &&msqueue[id]->mutex_buff );
- pos = msqueue[id]->curElementNum * msqueue[id]->elementLength;
- bcopy ( buff, &&msqueue[id]->buff[pos], msqueue[id]->elementLength );
- msqueue[id]->curElementNum ++;
- pthread_mutex_unlock ( &&msqueue[id]->mutex_buff );
- //如果插入消息前,消息队列是空的,插入消息后,消息队列为非空,则通知等待从消
- 息队列取消息的线程,条件满足,可以取出消息进行处理
- if ( msqueue[id]->curElementNum == 1 ) {
- pthread_mutex_lock ( &&msqueue[id]->mutex_cond );
- pthread_cond_broadcast ( &&msqueue[id]->cond );
- pthread_mutex_unlock ( &&msqueue[id]->mutex_cond );
- }
- return length;
- }
从Unix消息队列中接收消息:
消息队列的接收函数 msqueue_receive,其参数:id为消息队列数组的索引号,buff为
消息内容,length为消息长度。
- int msqueue_receive ( id, buff, length )
- int id, length;
- caddr_t buff;
- {
- caddr_t temp;
- int pos;
- if(id<0||id>=MAXQUEUE)return MQERROR;
- if(length != msqueue[id]->elementLength)
- return MQERROR;
- //如果消息队列为空,则等待,直到消息队列为非空条件满足
- if ( msqueue[id]->curElementNum == 0){
- pthread_mutex_lock ( &&msqueue[id]->mutex_cond );
- pthread_cond_wait ( &&msqueue[id]->cond, &&msqueue[id]->mutex_cond );
- pthread_mutex_unlock ( &&msqueue[id]->mutex_cond );
- }
- //取消息前,锁住消息队列缓冲区,以免其他线程存放或取消息
- pthread_mutex_lock ( &&msqueue[id]->mutex_buff );
- //为符合消息队列FIFO特性,取出消息后,进行消息队列的调整
- temp =
- malloc((msqueue[id]->curElementNum-1)
- msqueue[id]-elementLength );
- bcopy ( &&msqueue[id]->buff[0], buff, msqueue[id]->elementLength );
- msqueue[id]->curElementNum --;
- bcopy ( &&msqueue[id]->buff[msqueue[id]->elementLength], temp,
- msqueue[id]->elementLength
- msqueue[id]->curElementNum);
- bcopy ( temp, &&msqueue[id]->buff[0],
- msqueue[id]->elementLength
- msqueue[id]->curElementNum);
- free ( temp );
- //解除缓冲区锁
- pthread_mutex_unlock ( &&msqueue[id]->mutex_buff );
- return length;
- }
Unix消息队列的创建工作,我们就学习到这里了,希望大家能够学习如何创建Unix消息队列。
【编辑推荐】