- 论坛徽章:
- 44
|
回复 57# linux_c_py_php
用什么结构体保存连接本身的信息没关系,关键是如何把这些信息汇集起来
一个不动脑子的方案可以是这样:
1. 建立一个双链表
2. 新连接建立后,将连接信息插入表尾
- context->next=NULL;
- context->prev=tail;
- tail->next=context;
- tail=context;
复制代码 3. 连接结束后,将该连接从链表中摘除,在context中记录结束的时间戳,然后传递给后台的reaper thread
- context->prev->next=context->next;
- context->next->prev=context->prev;
- context->prev=reaper_list_tail;
复制代码 4. reaper thread维护另外一个反向的单链表,这个链表只使用/调整prev指针,不修改next指针,reaper定期扫描这个链表,将时间戳老于一定阈值的节点回收,其它节点不变。
- while(1) {
- context_t *p=reaper_list_tail;
- context_t *prev;
- while(prev=p, p=p->prev) {
- if(old_enough(p)){
- prev->prev=p;
- reap(p);
- }
- }
- }
复制代码 5. 遍历连接时,只单向遍历,只使用next指针,这样可以保证即使某个连接在遍历期间被放入了reaper链表,它的next依然指向一个存活的context(虽然不一定是有效的)
- for(context_t *p=head; p; p=p->next) {
- // do something with p
- }
复制代码 整个过程差不多就是这样。
上述代码只在ARM/X86/X86_64这些Strong Order的平台下能工作(前提是我脑子没发晕,代码没写错,这个可能性……哼哼……很小……),对于其它平台需要引入memory order,并且需要编译器不要自作聪明调整代码顺序。 |
|