Swoole源码学习记录(七)——MsgQueue

Swoole版本:1.7.5-beta

版本更换通知:从第七章开始,我把分析的源码版本升到了1.7.5-beta。在已经分析过的代码中存在了一些变动,但没有到会影响理解的地步,所以再次不再更新前面的章节。如果确认前面的章节有重大变更需要重新分析的,我会给出声明。

 

Swoole内部封装了Linux提供的msg queue用于提供消息队列的操作。消息队列的声明在swoole.h文件的360 – 378 行。声明如下:

typedef struct _swQueue_Data
{
         long mtype;                            /* type of received/sent message*/
         char mdata[sizeof(swEventData)];  /* text ofthe message */
} swQueue_data;
 
typedef struct _swQueue
{
         void *object;
         int blocking;
         int (*in)(struct _swQueue *, swQueue_data *in, int data_length);
         int (*out)(struct _swQueue *, swQueue_data *out, int buffer_length);
         void (*free)(struct _swQueue *);
         int (*notify)(struct _swQueue *);
         int (*wait)(struct _swQueue *);
} swQueue;
 
int swQueueMsg_create(swQueue *p, int wait,int msg_key, long type);

第一个结构体swQueue_Data封装了消息队列中的消息,其中mtype 用于标记该消息是需要发送的消息还是从队列中读出的消息,mdata用于存放消息内容(swEventData结构体将在下一章解析)。

最后一行的函数用于创建一个消息队列,第二个参数wait指定阻塞类型,msg_key指定创建的消息队列的键值,type标记消息队列读数据的类型

type=0,接受该队列的第一个消息,并将它返回给调用者

type>0,接受类型type的第一个消息

type<0,接受小于等于type绝对值的最低类型的第一个消息

swQueueMsg_create函数的具体声明在Msg.c文件中,其核心代码如下:

         swQueueMsg*object = sw_malloc(sizeof(swQueueMsg));
         if(object == NULL)
         {
                   return-1;
         }
         if(blocking == 0)
         {
                   object->ipc_wait= IPC_NOWAIT;
         }
         else
         {
                   object->ipc_wait= 0;
         }
         p->blocking= blocking;
         msg_id= msgget(msg_key, IPC_CREAT | O_EXCL | 0666);



源码解释:申请内存,分配消息队列的结构体内存,并判定消息队列的阻塞类型。接着调用msgget函数创建消息队列。

这里说明msgget第三个参数中的几个值的意义。IPC_CREAT表明,若不存在以key为索引的消息队列,则创建新的队列;否则,返回已创建的消息队列的id。O_EXCL表示若打开一个已存在的消息队列,则返回-1。0666为该消息队列的读写权限。

swQueueMsg有对应的三个操作函数,分别是:

int swQueueMsg_in(swQueue *p, swQueue_data*in, int data_length);
int swQueueMsg_out(swQueue *p, swQueue_data*out, int buffer_length);
void swQueueMsg_free(swQueue *p);

这三个函数用于向队列中写入消息、从队列中读出消息、释放队列。

1.      swQueueMsg_in函数循环调用msgsnd直到消息发送成功或无法再次发送。

2.      swQueueMsg_out函数调用msgrcv函数接收指定类型的消息

3.      swQueueMsg_free函数调用msgctl释放一个消息队列,IPC_RMID参数代表立即释放全部资源。

 

 PS:最近一直在忙面试和公司的事情,所以停更了很久。这次只更一个小章,下一个大章已经在写了,顺利的话会在明天放出。如果觉得我写的blog对你有所帮助,或者对我的分析有一些见解,欢迎在下方评论或发邮件给我。

我的邮箱地址:simonarthur2012@gmail.com



没有更多推荐了,返回首页