skynet源代码学习 - 从全局队列中弹出/压入一个消息队列过程

学习云风的skynet源代码,简单记录下。

void
skynet_globalmq_push(struct message_queue * queue) {
	struct global_queue *q= Q;

	uint32_t tail = GP(__sync_fetch_and_add(&q->tail,1));

	// only one thread can set the slot (change q->queue[tail] from NULL to queue)
	if (!__sync_bool_compare_and_swap(&q->queue[tail], NULL, queue)) {
		// The queue may full seldom, save queue in list
		// 假设swap失败说明queue[] 满了,达到了64K个队列,出现的几率非常小
		// 假设这种话,就把其保存在Q的list中
		assert(queue->next == NULL);
		struct message_queue * last;
		do {
			last = q->list;
			queue->next = last;
		} while(!__sync_bool_compare_and_swap(&q->list, last, queue));

		return;
	}
}

// 结构体global_queue中的 head, tail 字段分别控制着Q的取,存过程
// GP呢能够看做是一个hash的过程,以此来确定其维护的queues的index
struct message_queue *
skynet_globalmq_pop() {
	struct global_queue *q = Q;
	uint32_t head =  q->head;

	if (head == q->tail) {
		// The queue is empty.
		return NULL;
	}

	uint32_t head_ptr = GP(head);

	struct message_queue * list = q->list;
	// 假设list非空,说明Q->queue以前满过,就把他们转移回queue[]中,由于那里速度更快
	if (list) {
		// If q->list is not empty, try to load it back to the queue
		struct message_queue *newhead = list->next;
		if (__sync_bool_compare_and_swap(&q->list, list, newhead)) {
			// try load list only once, if success , push it back to the queue.
			list->next = NULL;
			skynet_globalmq_push(list);
		}
	}

	// 从头取一个消息队列
	struct message_queue * mq = q->queue[head_ptr];
	if (mq == NULL) {
		// globalmq push not complete
		return NULL;
	}
	// 取走一个消息后自然要将index往后移动一个位置,而且刚那个position置为空
	if (!__sync_bool_compare_and_swap(&q->head, head, head+1)) {
		return NULL;
	}
	// only one thread can get the slot (change q->queue[head_ptr] to NULL)
	if (!__sync_bool_compare_and_swap(&q->queue[head_ptr], mq, NULL)) {
		return NULL;
	}

	return mq;
}
时间: 2024-08-01 10:45:35

skynet源代码学习 - 从全局队列中弹出/压入一个消息队列过程的相关文章

skynet源码学习 - 从全局队列中弹出/压入一个消息队列过程

学习云风的skynet源码,简单记录下. void skynet_globalmq_push(struct message_queue * queue) { struct global_queue *q= Q; uint32_t tail = GP(__sync_fetch_and_add(&q->tail,1)); // only one thread can set the slot (change q->queue[tail] from NULL to queue) if (!_

如果让你写一个消息队列,该如何进行架构设计啊?说一下你的思路

1.面试官心里分析 其实聊到这个问题,一般面试官要考察两块: (1)你有没有对某一个消息队列做过较为深入的原理的了解,或者从整体了解把握住一个mq的架构原理 (2)看看你的设计能力,给你一个常见的系统,就是消息队列系统,看看你能不能从全局把握一下整体架构设计,给出一些关键点出来 说实话,我一般面类似问题的时候,大部分人基本都会蒙,因为平时从来没有思考过类似的问题,大多数人就是平时埋头用,从来不去思考背后的一些东西.类似的问题,我经常问的还有,如果让你来设计一个spring框架你会怎么做?如果让你

消息队列入门(一)关于消息队列

什么是消息队列 消息是指在两个独立的系统间传递的数据,这两个系统可以是两台计算机,也可以是两个进程. 消息可以非常简单,可以是简单的字符串,也可以是保存了数据持久化的各种类型的文档集合. 队列是在消息的传输过程中的通道,是保存消息的容器,根据不同的情形,可以有先进先出,优先级队列等区别 . 为什么使用消息队列 个人觉得消息队列主要的意义是解耦和异步处理,以及在高并发场景下平滑短时间内大量的服务请求. 消息队列不仅被用于系统内部组件之间的通信,同时也被用于系统跟其它服务之间的交互. 消息队列的使用

栈的弹出压入序列(C++)

题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列.(注意:这两个序列的长度是相等的) 分析:以压入1,2,3,4,5,弹出4,5,3,2,1为例,首先压入与弹出序列用vector执行,接受需要stack(先进后出),每压入一个元素都需要与与弹出序列判等,如果相等直接pop()

使用NODEJS+REDIS开发一个消息队列以及定时任务处理

作者:RobanLee 原创文章,转载请注明: 萝卜李 http://www.robanlee.com 源码在这里: https://github.com/robanlee123/RobCron 时间有限,就不详细注释,有问题或者意见欢迎@我,也欢迎大家批评指正. 本文所必须的一些资料如下: 1. NODEJS ==> 可以去NODEJS.ORG下载最新的源码.2. Redis ==> Redis.io3. KUE ==> Nodejs的一个开源队列系统4. NODE-SCHEDULE

如何使用NODEJS+REDIS开发一个消息队列

作者: RobanLee 原创文章,转载请注明: 萝卜李 http://www.robanlee.com MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们>.消 息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术.排队指的是应用程序通过 队列来通信.队列的使用除去了接收和发送应用程序同时执行的要求.其

C中级 消息队列设计

引言  - 补充好开始 消息队列在游戏服务器层应用非常广泛. 应用于各种耗时的IO操作业务上.消息队列可以简单理解为 [消息队列 = 队列 + 线程安全]本文参照思路如下, 最后献上一个大神们斗法的场景O(∩_∩)O哈哈~  回调还是消息队列     -> 架构的选择 skynet 全局消息队列 -> skynet_mq.c   消息队列血案 https://www.douban.com/note/470290075/ 消息队列最方便之处在于让异步编程变得简单高效.(异步搞成同步). 多数应用

消息队列设计精要(转)

消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之一.当今市面上有很多主流的消息中间件,如老牌的ActiveMQ.RabbitMQ,炙手可热的Kafka,阿里巴巴自主开发的Notify.MetaQ.RocketMQ等.本文不会一一介绍这些消息队列的所有特性,而是探讨一下自主开发设计一个消息队列时,你需要思考和设计的重要方面.过程中我们会参考这些成熟消息队列的很多重要思想.本文首先会阐述什么时候你需要一个消

【转】消息队列设计精要

介绍的比较全面,可以借鉴学习:原文连接:http://tech.meituan.com/mq-design.html 消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之一.当今市面上有很多主流的消息中间件,如老牌的ActiveMQ.RabbitMQ,炙手可热的Kafka,阿里巴巴自主开发的Notify.MetaQ.RocketMQ等.本文不会一一介绍这些消息队列的所有特性,而是探讨一下自主开发设计一个消息