wangzhengquan
2021-02-04 4a79808836b1ec5e10ab686c6241f4c9fb99f40f
update
1个文件已删除
1个文件已添加
2 文件已重命名
43 ■■■■ 已修改文件
doc/Bus设计方案.md 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/product-consume-model.png 补丁 | 查看 | 原始文档 | blame | 历史
doc/rdma/rdma通信接口包.txt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/共享队列综合设计.png 补丁 | 查看 | 原始文档 | blame | 历史
doc/BusÉè¼Æ·½°¸.md
File was renamed from doc/»ùÓÚ¹²ÏíÄÚ´æµÄÉú²úÕßÏû·ÑÕßģʽµÄÎÞËø¶ÓÁеÄÉè¼Æ·½°¸.md
@@ -1,32 +1,50 @@
# åŸºäºŽå…±äº«å†…存的生产者消费者模式的无锁队列的实现
# Bus è®¾è®¡æ–¹æ¡ˆ
## 1 æ•´ä½“设计
## 1 ä¸Šå±‚业务逻辑设计
### 1.1 Bus设计
### 1.1 æ€»çš„æµç¨‹å¦‚下:
![Bus示意图](./bus_service.png)
上面这张示意图是说订阅news的Client有A和B,订阅sports的有B和C,这些都在总线里记录着。当A向总线pub和主题sports相关的内容时,B和C会通过总线收到这个主题的消息。
### 1.2 NetProxyService设计
![NetProxyService示意图](./network_req_rep.png)
上面这张图跨机器请求应答的示意图。这张示意图时说当节点A向节点B的key 1001队列和key 1002队列发送消息时,它会首先发送到节点B的网络代理server上。网络代理server会把请求消息转发到相应的队列上,并接受应答返回给节点A。
同理跨机器的发布订阅也是通过这样的方式交互的。
## 2 æ¶ˆæ¯é˜Ÿåˆ—设计
### 2.1 æ€»çš„æµç¨‹å¦‚下:
1.  å…¥é˜Ÿæ“ä½œï¼šé˜Ÿåˆ—向内存管理器申请一块内存,内存管理器从内存的自由分配区分配一块内存返回给队列。
2.  å‡ºé˜Ÿæ“ä½œï¼šé˜Ÿåˆ—向内存管理器发去释放内存的请求,内存管理器释放该内存块以供下次使用。
### 1.2 å…±äº«å†…存的的划分
Queue对象内部记录了队列头和队列尾的位置,通过它们自然可以找到每个队列节点的位置。但是Queue对象自己也在共享内存里面,第一个创建Queue对象的进程自然知道Queue对象的位置,但是必须让其他的进程也知道Queue对象的位置,所以就约定一个规则把Queue对象放在一个大家都知道的位置,这里选择了共享内存的起始位置。内存管理器不会对这块区域进行操作,在此之后的那块内存自由分配区才是内存管理器管理的区域。如下图:
![](./queue_coopration.png.png)
![](./共享队列综合设计.png)
## 2 æ— é”é˜Ÿåˆ—(Free Lock)的实现
### 2.2 æ— é”é˜Ÿåˆ—(Free Lock)的实现
无锁队列是用细粒度的原子锁实现的,多进程操作时无阻塞并发性能高。网上有五花八门的相关算法实现。我对比了一下,决定采用下面的这个。这个算法性能好是一方面,它同时也解决了队列为空时并发操作可能出现的问题,以及ABA的问题。
![](./linked-lock-free-code.png)
## 3 ç”Ÿäº§è€…消费者之间的协作
### 2.3 æ¶ˆæ¯é˜Ÿåˆ—的生产者消费者模式
> ä»¥ä¸‹è¯´æ˜Žä¸åŒ…括无等待和超时的情况
生产者消费者之间的相互协作时通过信号实现的,信号量slots代表队列空闲的数量,信号量items代表已插入队列的数量。队列初始化时,slots等于队列的最大长度,items等于0。入队时slots减一,items加1。出队时items减一,slots加1。队列已满时slots的量必然等于0,生产者进入等带状态,有空闲位置的时候会恢复执行。队列为空时items的量必然为0,消费者进入等待状态,有新成员入队的时候会恢复执行。具体协作关系如下图:
![生产者消费者模型](./生产者消费者模型.png)
![生产者消费者模型](./product-consume-model.png)
## 4 å†…存管理器
## 3 å…±äº«å†…存的内存管理器设计
要实现对内存的管理,就要记录每个已分配块和空闲块的信息。这些信息就记录在每个块的头部和尾部。这些信息包括块的大小(Block size), æ˜¯å¦å·²åˆ†é…ï¼ˆa表示已分配,f表示空闲),其中空闲块比已分配块还多了两个信息(前驱节点指针predecessor, åŽç»§èŠ‚ç‚¹æŒ‡é’ˆsuccessor),分别指向前一个和后一个空闲块的指针。如下图:
doc/product-consume-model.png

doc/rdma/rdmaͨÐŽӿڰü.txt
New file
@@ -0,0 +1 @@
    https://github.com/linux-rdma/rdma-core.git
doc/¹²Ïí¶ÓÁÐ×ÛºÏÉè¼Æ.png
Binary files differ