skynet消息队列一文搞定

本文介绍了Skynet系统中的全局消息队列实现,它基于单链表结构,包括message_queue结构和global_queue结构。主要讲解了初始化、添加到队列尾部(push)和从队列头部移除(pop)的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

struct message_queue {

    //锁

    struct spinlock lock;

    //消息队列所属服务的句柄(用于消息处理)

    uint32_t handle;

    //队列容量

    int cap;

    //取出标志

    int head;

    //存入标志

    int tail;

    //队列是否已被释放表示(0为未释放,1为已释放)

    int release;

    //是否存入全局消息队列标志

    int in_global;

    int overload;

    int overload_threshold;

    //skynet_message消息队列(其实是一个数组通过queue[序号]从队列中获取指定的消息)

    struct skynet_message *queue;

    //与其他消息队列的关联(非空表示在全局消息队列中)

    struct message_queue *next;

};

不难看出来,全局消息队列看起来像是一个 单链表 ,每个节点都带着一个struct message_queue *next;指向下一个节点

//全局消息队列结构

struct global_queue {

struct message_queue *head;

struct message_queue *tail;

//锁(自旋锁或互斥锁)

struct spinlock lock;

};

//全局消息队列的静态结构指针

static struct global_queue *Q = NULL;

全局消息队列其实就是一个头,Windows叫HeadList,此队列向尾部添加,从头部取出删除,分别用 struct message_queue *head;和 struct message_queue *tail;记录其首尾下标。

真正创建全局消息队列的实现在下面函数中:

//初始化全局消息队列

void skynet_mq_init() {

//创建全局消息队列

struct global_queue *q = skynet_malloc(sizeof(*q));

//将*q指针所占存储全部初始化为0

memset(q,0,sizeof(*q));

//初始化全局消息队列中的锁

SPIN_INIT(q);

//将创建结果保存在静态指针中

Q=q;

}

可见,只创建一个struct global_queue 结构并赋值给全局指针对象Q

//将服务的消息队列放入全局消息队列尾

void

skynet_globalmq_push(struct message_queue * queue) {

struct global_queue *q= Q;

SPIN_LOCK(q)

assert(queue->next == NULL);

if(q->tail) {

q->tail->next = queue;//挂载到Q->tail的next上

q->tail = queue;//然后把queue赋值给q->tail,这样其他message_queue *就可以挂到当前节点queue的next上了

} else {

q->head = q->tail = queue; //没挂载任何struct message_queue *使其首位相连

}

SPIN_UNLOCK(q)

}

//从全局消息队列头中弹出一条二级消息队列

struct message_queue *

skynet_globalmq_pop() {

struct global_queue *q = Q;

SPIN_LOCK(q)

struct message_queue *mq = q->head;

if(mq) {

q->head = mq->next;

if(q->head == NULL) {

assert(mq == q->tail);

q->tail = NULL;

}

mq->next = NULL;

}

SPIN_UNLOCK(q)

return mq;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值