poll

Ble Mesh技术(九)之Friendship

落花浮王杯 提交于 2020-01-17 08:11:19
Friend直接流程建立都是通过上层传输曾的控制PDU进行交互。控制消息大部分都为不分段消息,所以这一章我们以下层传输层的为分段消息作为PDU格式的总体示意图。 1. Friendship相关Control PDU 1.1. Friend Poll 由LPN发起,请求Friend发送LPN睡眠期间为LPN存储的消息。 Opcode=0x01,对应的Parameters如下所示: Field Size(bits) Notes Padding 7 0b0000000,固定值 FSN 1 Friend Sequence Number TTL域设置为0。 消息使用 friendship security credentials加密。 1.2. Friend Update Friend通知LPN安全参数已经改变,或者当前消息队列为空。 Opcode=0x02,对应的Parameters如下所示: Field Size(octets) Notes Flags 1 第0个bit表示当前的Key Refresh阶段 第1个bit表示当前的IV Update状态 第2-7位RFU IV Index 4 Friend节点当前的IV Index MD 1 MD=0:表明Friend Queue为空 MD=1:表明Friend Queue非空 Field Notes Key Refresh Flag 0

Kafka--Consumer消费者

冷暖自知 提交于 2020-01-13 13:11:47
转:https://www.cnblogs.com/dingwpmz/p/12185196.html 温馨提示:整个 Kafka 专栏基于 kafka-2.2.1 版本。 1、KafkaConsumer 概述 根据 KafkaConsumer 类上的注释上来看 KafkaConsumer 具有如下特征: 在 Kafka 中 KafkaConsumer 是线程不安全的。 2.2.1 版本的KafkaConsumer 兼容 kafka 0.10.0 和 0.11.0 等低版本。 消息偏移量与消费偏移量(消息消费进度) Kafka 为分区中的每一条消息维护一个偏移量,即消息偏移量。这个偏移量充当该分区内记录的唯一标识符。消费偏移量(消息消费进度)存储的是消费组当前的处理进度。消息消费进度的提交在 kafka 中可以定时自动提交也可以手动提交。手动提交可以调用 ommitSync() 或 commitAsync 方法。 消费组 与 订阅关系 多个消费这可以同属于一个消费组,消费组内的所有消费者共同消费主题下的所有消息。一个消费组可以订阅多个主题。 队列负载机制 既然同一个消费组内的消费者共同承担主题下所有队列的消费,那他们如何进行分工呢?默认情况下采取平均分配,例如一个消费组有两个消费者c1、c2,一个 topic 的分区数为6,那 c1 会负责3个分区的消费,同样 c2

nodejs源码解析之事件循环

China☆狼群 提交于 2020-01-13 04:02:18
nodejs的的事件循环由libuv的uv_run函数实现。在该函数中执行while循环,然后处理各种阶段(phase)的事件回调。事件循环的处理相当于一个消费者,消费由各业务代码生产的任务。下面看一下代码。 int uv_run ( uv_loop_t * loop , uv_run_mode mode ) { int timeout ; int r ; int ran_pending ; r = uv__loop_alive ( loop ) ; if ( ! r ) uv__update_time ( loop ) ; while ( r != 0 && loop -> stop_flag == 0 ) { // 更新loop的time字段 uv__update_time ( loop ) ; // 执行超时回调 uv__run_timers ( loop ) ; // 执行pending回调,ran_pending代表pending队列是否为空,即没有节点可以执行 ran_pending = uv__run_pending ( loop ) ; // 继续执行各种队列 uv__run_idle ( loop ) ; uv__run_prepare ( loop ) ; timeout = 0 ; // UV_RUN_ONCE并且有pending节点的时候,会阻塞式poll

c coroutine

半世苍凉 提交于 2020-01-12 23:52:34
今天看了下云风写的关于 c coroutine 博客 ( 代码 ), 发现 coroutine 实现原理其实还比较简单,就用户态栈切换,只需要几十行汇编,特别轻量级。 具体实现 1. 创建一个coroutine: 也就是创建一块连续内存,用于存放栈空间,并设置好入口函数所需要的寄存器   makecontext glibc c语言实现 2. resume coroutine: push保存当前执行上下文的寄存器到栈上,修改%rsp寄存器, jmp 到指定coroutine 执行指令位置,pop 恢复寄存器,开始执行 swapcontext glibc 汇编实现 3. yield coroutine: 同resume 栈切换涉及寄存器操作,得用汇编实现, x86 8个通用寄存器,x64 16个,通过push 保存到栈,pop 恢复到寄存器;比较重要寄存器%rsp 栈顶指针,%rip 指令指针不能直接操作,通过call、jmp 跳转新的Code执行位置。 在64汇编中,并不需要对16个寄存器都备份,其中%rax作为返回值、%r10 %r11 被调用方使用前会自己备份. 参考: X86-64寄存器和栈帧 X86-64寄存器的变化,不仅体现在位数上,更加体现在寄存器数量上。新增加寄存器%r8到%r15。加上x86的原有8个,一共16个寄存器。 刚刚说到,寄存器集成在CPU上

Java 集合框架(四):PriorityQueue 和 ConcurrentLinkedQueue

匆匆过客 提交于 2020-01-12 22:26:42
Queue 队列是一种支持 FIFO 的数据结构或者容器。Queue 接口下面的实现类包括 Deque,非阻塞队列和阻塞队列。 PriorityQueue PriorityQueue 是一个基于优先级的无界队列。比如我们的作业系统中,当一个作业完成后,在所有等待调度的作业中选择一个优先级最高的作业来执行,并且可以添加新的作业到优先队列中。 特点: 元素按照自然顺序进行排列或者根据传入的 Comparator 进行排序。 不允许插入 null 或者不可比较的对象(没有实现 Comparable 接口的对象)。 优先级队列的头部元素最小(底层是一个最小堆)。 底层实现是一个数组,会根据元素的数量进行扩容。 线程不安全的 方法分析: 先来看这个优先级队列的构成,我们发现了一个非常重要的问题,就是优先级队列的底层是一个数组。 public class PriorityQueue<E> extends AbstractQueue<E> implements java.io.Serializable { transient Object[] queue; //队列容器, 默认是11 private int size = 0; //队列长度 private final Comparator<? super E> comparator; //队列比较器, 为null使用自然排序 //.... }

Redis 单线程却能支撑高并发 - 简书 https://www.jianshu.com/p/2d293482f272

时间秒杀一切 提交于 2020-01-09 18:14:33
小结: 1、 在 I/O 多路复用模型中,最重要的函数调用就是 select,该方法的能够同时监控多个文件描述符的可读可写情况; 2、 Redis 服务采用 Reactor 的方式来实现文件事件处理器(每一个网络连接其实都对应一个文件描述符); 3、 虽然整个文件事件处理器是在单线程上运行的,但是通过 I/O 多路复用模块的引入,实现了同时对多个 FD 读写的监控,提高了网络通信模型的性能,同时也可以保证整个 Redis 服务实现的简单 4、 Redis 会优先选择时间复杂度为 O(1) 的 I/O 多路复用函数作为底层实现,包括 Solaries 10 中的 evport、Linux 中的 epoll 和 macOS/FreeBSD 中的 kqueue,上述的这些函数都使用了内核内部的结构,并且能够服务几十万的文件描述符。 但是如果当前编译环境没有上述函数,就会选择 select 作为备选方案,由于其在使用时会扫描全部监听的描述符,所以其时间复杂度较差 O(n),并且只能同时服务 1024 个文件描述符,所以一般并不会以 select 作为第一方案使用。 https://mp.weixin.qq.com/s/ySG2Qtitr6b8Zcb-SAMnGQ Redis 和 I/O 多路复用 https://draveness.me/redis-io-multiplexing

Java队列(Queue)了解及使用

一曲冷凌霜 提交于 2020-01-09 03:57:30
1.什么是队列? 队列是数据结构中比较重要的一种类型(是一种数据结构),它支持 FIFO,尾部添加、头部删除(先进队列的元素先出队列),跟我们生活中的排队类似。 2.什么情况下使用队列? 一般情况下,如果是对一些及时消息的处理,并且处理时间很短的情况下是不需要队列的,直接阻塞式的方法调用就可以了。但是如果在消息处理的时候特别费时间,这个时候如果有新消息来了,就只能处于阻塞状态,造成用户等待。这个时候便需要引入队列了。当接收到消息后,先把消息房贷队列中,然后再用行的线程进行处理,这个时候就不会有消息阻塞了。 3.队列介绍: 队列有两种: ① 单队列 : 就是常见的队列,每次添加元素时,都是添加对队尾。 ② 循环队列(暂不介绍) 4.队列Queue add 增加一个元索 如果队列已满,则抛出一个IIIegaISlabEepeplian异常   remove 移除并返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常   element 返回队列头部的元素 如果队列为空,则抛出一个NoSuchElementException异常   offer 添加一个元素并返回true 如果队列已满,则返回false   poll 移除并返问队列头部的元素 如果队列为空,则返回null   peek 返回队列头部的元素 如果队列为空,则返回null   put

Nginx 事件基本处理流程分析

萝らか妹 提交于 2020-01-09 00:32:40
说明:本文章重点关注事件处理模型。有兴趣的同学可以去 http://tengine.taobao.org/book/ 查找更多资料。Tengine应该是淘宝基于Nginx自己做的修改。这个地址的文档还在不断的完善更新中,内容算是比较全面的。 程序流程图: 说明: 一、进程生成顺序 1.main(src/core/nginx.c)函数启动ngx_master_process_cycle,启动主服务进程。 2.ngx_master_process_cycle(src/os/unix/ngx_process_cycle.c)里面调用ngx_start_worker_processes. 3.ngx_start_worker_processes(src/os/unix/ngx_process_cycle.c)里面循环执行 生成特定数量的进程池。 4.ngx_spawn_process(src/os/unix/ngx_process.c)根据指定的respawn选项fork子进程,相关子进程信息保存在全部ngx_processes数组(ngx_process_t ngx_processes[NGX_MAX_PROCESSES])中,子进程的运行过程通过参数proc指定,这里是ngx_worker_process_cycle(src/os/unix/ngx_process_cycle.c)

django实例:创建你的第一个应用投票系统(3)后台管理

百般思念 提交于 2020-01-07 09:23:46
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> Django的管理面板默认是不开启的,所以我们需要进行一些设置工作 1、在INSTALLED_APPS里面把 django.contrib.admin 前面的注释去掉 2、运行 python manage.py syncdb ,建立和管理有关的表 3、编辑mysite/urls.py文件,设置管理面板的url路由规则 from django.conf.urls import patterns, include, url # Uncomment the next two lines to enable the admin: from django.contrib import admin admin.autodiscover() urlpatterns = patterns( '' , # Examples: # url(r'^现在启动服务<div class="blockcode"><blockquote>python manage.py runserver 访问 http://127.0.0.1:8000/admin/ 会看到管理登录页面 输入用户名和密码,就在上一节创建的超级用户 当然现在还是看不到我们添加的投票管理项 在polls目录下面添加admin.py页面,内容如下 from django