- 浏览: 1407111 次
- 性别:
- 来自: 火星
-
最新评论
-
aidd:
内核处理time_wait状态详解 -
ahtest:
赞一下~~
一个简单的ruby Metaprogram的例子 -
itiProCareer:
简直胡说八道,误人子弟啊。。。。谁告诉你 Ruby 1.9 ...
ruby中的类变量与类实例变量 -
dear531:
还得补充一句,惊群了之后,数据打印显示,只有一个子线程继续接受 ...
linux已经不存在惊群现象 -
dear531:
我用select试验了,用的ubuntu12.10,内核3.5 ...
linux已经不存在惊群现象
文章列表
我们来看tcp输入对于ack,段的处理。
先是ack的处理,在内核中,处理ack段是通过tcp_ack来进行的。
这个函数主要功能是:
1 update重传队列,并基于sack来设置skb的相关buf。
2 update发送窗口。
3 基于sack的信息或者重复ack来决定是否进入拥塞模式。
在看之前我们要知道tcp是累积确认的。为了解决带来的缺点,我们才需要sack的。
然后我们来看几个很重要的数据结构,先是tcp_skb_cb,它其实就是表示skb中所保存的tcp的控制信息。而他是保存在skb的cb中的(这个域可以看我前面的blog)。所以这里我们经常会用TCP_SKB_CB ...
这次来详细看内核的time_wait状态的实现,在前面介绍定时器的时候,time_wait就简单的介绍了下。这里我们会先介绍tw状态的实现,然后来介绍内核协议栈如何处理tw状态。
首先我们要知道在linux内核中time_wait的处理是由tcp_time_wait这个函数来做得,比如我们在closing状态收到一个fin,就会调用tcp_time_wait.而内核为time_wait状态的socket专门设计了一个结构就是inet_timewait_sock,并且是挂载在inet_ehash_bucket的tw上(这个结构前面也已经介绍过了)。这里要注意,端口号的那个hash链表中也是会保存 ...
惊群也就是指多个进程阻塞在accept,当有连接完成,会唤醒所有进程。
经过测试,发现现在的内核已经修复了这个问题,当有多个进程阻塞在accept,只会唤醒一个进程。
下面这个是一篇论文,就是讲这个问题的。
http://www.usen ...
首先我们来看socket如何将一些状态的变化通知给对应的进程,比如可读,可写,出错等等。
先来看sock结构中这几个相关域:
struct sock {
..........................
wait_queue_head_t *sk_sleep;
.....................................
void (*sk_state_change)(struct sock *sk);
void (*sk_data_ready)(struct sock *sk, int bytes);
void (*sk_write_space)(str ...
我看的内核版本是2.6.32.
在内核中sk_buff表示一个网络数据包,它是一个双向链表,而链表头就是sk_buff_head,在老的内核里面sk_buff会有一个list域直接指向sk_buff_head也就是链表头,现在在2.6.32里面这个域已经被删除了。
而sk_buff的内存布局可以分作3个段,第一个就是sk_buff自身,第二个是linear-data buff,第三个是paged-data buff(也就是skb_shared_info)。
ok.我们先来看sk_buff_head的结构。它也就是所有sk_buff的头。
struct sk_buff_head { ...
这次简单的补充一下前面类型部分剩下的东西。
首先我们要知道当我们想为lua来编写扩展的时候,有时候可能需要一些全局变量。可是这样会有问题,这是因为这样的话,我们就无法用于多个lua状态(也就是new 多个state).
于是lua提供了三种可以代替全局变量的方法。分别是注册表,环境变量和upvalue。
其中注册表和环境变量都是table。而upvalue也就是我们前面介绍的用来和指定函数关联的一些值。
由于lua统一了从虚拟的栈上存取数据的接口,而这三个值其实并不是在栈上保存,而lua为了统一接口,通过伪索引来存取他们。接下来我们就会通过函数index2adr的代码片断来分析这三个类型 ...
tcp是全双工的协议,因此每一端都会有流控。一个tcp段有可能是一个数据段,也有可能只是一个ack,异或者即包含数据,也包含ack。如果是数据段,那么有可能是in-sequence的段,也有可能是out-of-order的段。如果是in-sequence的段,则马上加入到socket的receive队列中,如果是out-of-order的段,则会加入到socket的ofo队列。一旦当我们接收到数据,要么立即发送ack到对端,要么延迟等待和后面的数据一起将ack发送出去。
当发送ack之前,我们需要检测一些我们已经从对端得到的信息。也就是说我们需要通过对端的信息来执行ack的生成。详细的去看tc ...
先来看内存池的实现,nginx的内存池实现的非常简单。
这里内存池的一些图表可以看老朱同学的slides :
http://blog.zhuzhaoyuan.com/2009/09/nginx-internals-slides-video/
当内存池初始化的时候(下面会分析到)ngx_poll_s只相当于内存池的一个头,保存了当前内存池的一些必要信息而已。
当从内存池存取数据的时候,nginx是分为两种类型来处理得,一种是小块数据,它是直接从内存池中取得数据,另一方面,当为大块数据时,它是直接malloc一块数据(也就是从内存池外部分配数据),然后保存这个指针到内存池。可以看到很多内存池 ...
这次紧接着上次的,将gc类型的数据分析完毕。
谢谢老朱同学的指正,这里CClosure和LClosure理解有误.
先来看闭包:
可以看到闭包也是会有两种类型,这是因为在lua中,函数不过是一种特殊的闭包而已。
更新:这里CClosure表示是c函数,也就是和lua外部交互传递进来的c函数以及内部所使用的c函数.
LClosure表示lua的函数,这些函数是由lua虚拟机进行管理的..
typedef union Closure {
CClosure c;
LClosure l;
} Closure;
接下来来看这个两个结构。
在看着两个结构之前,先来看宏Cl ...
我们先来看tcp内存管理相关的几个内核参数,这些都能通过proc文件系统来修改:
///内核写buf的最大值.
extern __u32 sysctl_wmem_max;
///协议栈读buf的最大值
extern __u32 sysctl_rmem_max;
这两个值在/proc/sys/net/core 下。这里要注意,这两个值的单位是字节。
它们的初始化在sk_init里面,这里可以看到这两个值的大小是依赖于num_physpages的,而这个值应该是物理页数。也就是说这两个值依赖于物理内存:
void __init sk_init(void)
{
if (num ...
- 2009-11-28 17:13
- 浏览 12131
- 评论(1)
先来看lua中值的表示方式。
#define TValuefields Value value; int tt
typedef struct lua_TValue {
TValuefields;
} TValue;
其中tt表示类型,value也就是lua中对象的表示。
typedef union {
GCObject *gc;
void *p;
lua_Number n;
int b;
} Value;
gc用于表示需 ...
我的gcc版本是4.4.1
先来看const和define以及enum定义,编译器会做什么样的优化:
enum { constant=23 };
#define CONSTANT 23
static const int Static_Constant=23;
const int Constant = 23;
int foo() {
a(constant+3);
a(CONSTANT+4);
a(Static_Constant+5);
return Static_Constant + Constant;
}
ok,我们然后来看对应的汇编 ...
- 2009-11-10 00:44
- 浏览 5191
- 评论(2)
IA32的cpu操作模式
1保护模式:
这个模式是cpu的native状态.它可以在一个保护的多任务的环境中直接执行 "real-address mode"的8086的软件.这个特性叫做virtual-8086模式.
这个模式也就是cpu的一般工作模式.因为这个模式基本上打开了cpu的所有特性.
2 real-address模式:
这个模式它实现了一个8086处理器的环境的扩展.换句话说,可以说是模拟了一个8086的程序环境.
计算机在重启或者开机的时候就处于这个模式,因此每次开机需要操作系统来切换到保护模式.这个模式中很多cpu的特性都是被关闭的.
3 sys ...
- 2009-11-08 20:06
- 浏览 6425
- 评论(0)
由于linux还不是一个实时的操作系统,因此如果需要更高精度,或者更精确的定时的话,可能就需要打一些实时的补丁,或者用商用版的实时linux,.
这里内的定时器最小间隔也就是1个tick.
这里还有一个要注意的,我这里的分析并没有分析内核新的hrt 定时器.这个定时器是Monta Vista加入到内核的一个高精度的定时器的实现.
先来看几个相关的数据结构.
///这个是一个最主要的数据结构,表示一个完整的定时器级联表
struct tvec_base {
///自旋锁
spinlock_t lock;
///表示由本地cpu正在处理的定时器链表
struct timer_list ...
- 2009-10-31 01:44
- 浏览 10217
- 评论(0)
主要是介绍一下常用的内存管理算法以及相关的数据结构.
三种类型:
1 sequential fit
包括first fit,next fit,以及best fit
这种算法的实现基本来说都是基于一个双向链表或者循环链表来保存所有的free memory.而且一般都会使用kunth的boundar ...
- 2009-10-28 20:05
- 浏览 10323
- 评论(0)