学习云风的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;
}

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

  1. 什么鬼,面试官竟然让我用Redis实现一个消息队列!!?

    GitHub 9.4k Star 的Java工程师成神之路 ,不来了解一下吗? GitHub 9.4k Star 的Java工程师成神之路 ,真的不来了解一下吗? GitHub 9.4k Star 的 ...

  2. 用过消息队列?Kafka?能否手写一个消息队列?懵

    是否有同样的经历?面试官问你做过啥项目,我一顿胡侃,项目利用到了消息队列,kafka,rocketMQ等等. 好的,那请开始你的表演,面试官递过一支笔:给我手写一个消息队列!!WHAT? 为了大家遇到 ...

  3. 进阶高阶IoT架构-教你如何简单实现一个消息队列

    前言 消息队列是软件系统领域用来实现系统间通信最广泛的中间件.基于消息队列的方式是指由应用中的某个系统负责发送消息,由关心这条消息的相关系统负责接收消息,并在收到消息后进行各自系统内的业务处理.消息可 ...

  4. skynet源代码学习 - logger工程和服务

    当skynet启动的时候,会依据配置文件制定的日志文件来创建一个logger context.详细过程就是找到logger.so动态链接文件.而后调用其logger_create函数(參数是配置的日志 ...

  5. RabbitMQ消息队列入门(一)——RabbitMQ消息队列的安装(Windows环境下)

    一.RabbitMQ介绍1.RabbitMQ简介RabbitMQ是一个消息代理:它接受和转发消息.你可以把它想象成一个邮局:当你把你想要发布的邮件放在邮箱中时,你可以确定邮差先生最终将邮件发送给你的收 ...

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

    作者:RobanLee 原创文章,转载请注明: 萝卜李 http://www.robanlee.com 源码在这里: https://github.com/robanlee123/RobCron 时间 ...

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

    作者: RobanLee 原创文章,转载请注明: 萝卜李 http://www.robanlee.com MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.应 ...

  8. 获取和设置消息队列的属性msgctl,删除消息队列

    消息队列的属性保存在系统维护的数据结构msqid_ds中,用户可以通过函数msgctl获取或设置消息队列的属性. int msgctl(int msqid, int cmd, struct msqid ...

  9. 聊聊高并发(十四)理解Java中的管程,条件队列,Condition以及实现一个堵塞队列

    这篇里面有一些主要的概念,理解概念是件有意义的事情,仅仅有理解概念才干在面对详细问题的时候找到正确的解决思路.先看一下管程的概念 第一次在书上看到管程这个中文名称认为非常迷糊,管程究竟是个什么东东,于 ...

随机推荐

  1. TimeUnit

    转http://blog.csdn.net/hudashi/article/details/6936604 public enum TimeUnitextends Enum<TimeUnit&g ...

  2. php Smarty模板引擎配置与测试

    Smarty简介 smarty是一个使用PHP写出来的模板PHP模板引擎,它提供了逻辑与外在内容的分离,简单的讲,目的就是要使用PHP程序员同美工分离,使用的程序员改变程序的逻辑内容不会影响到美工的页 ...

  3. Linux 经典电子书共享下载

    Linux 经典电子书共享下载 Linux网络管理员指南--Linux领域两位领导人物的作品—相当于“Linux 文档项目”.rar vim用户手册_603.0.pdf [Linux系统管理技术手册( ...

  4. PHP - 接口 - 多接口

    /* * 使用多接口 */ //定义接口1 interface IPerosn_one{ public function eat(); } //定义接口2 interface IPerson_two{ ...

  5. Java基础09 类数据与类方法

    链接地址:http://www.cnblogs.com/vamei/archive/2013/03/31/2988622.html 作者:Vamei 出处:http://www.cnblogs.com ...

  6. Got a packet bigger than 'max_allowed_packet' bytes With statement Mysql终端数据同步不成功解决办法

    在做两个数据库数据拷贝的时候,遭遇 1153 - Got a packet bigger than 'max_allowed_packet' bytes With statement: 遇到这个问题, ...

  7. boost::property_tree读取解析ini文件--推荐

    boost::property_tree读取解析ini文件 #include "stdafx.h" #include <iostream> #include <b ...

  8. ICMP:Internet控制报文协议

    ICMP:Internet控制报文协议. 是IP层的组成部分.传递差错报文或其他信息. ICMP报文被封装在IP数据报内部: 详细格式例如以下所看到的: 个字段含义例如以下: 8位类型. 表示该ICM ...

  9. codeforces 148D 概率DP

    题意: 原来袋子里有w仅仅白鼠和b仅仅黑鼠 龙和王妃轮流从袋子里抓老鼠. 谁先抓到白色老师谁就赢. 王妃每次抓一仅仅老鼠,龙每次抓完一仅仅老鼠之后会有一仅仅老鼠跑出来. 每次抓老鼠和跑出来的老鼠都是随 ...

  10. JDK自己主动拆箱下,三目运算符的潜规则

    近期发现了一个非常诡异的NullPointerException,在以下这种方法抛出,一開始怎么都没想明确,dSrc即使为null,那直接赋值给distinct也没问题啊. private Doubl ...