Intelligence without ambition is a bird without wings.

2016-03-11
TCP连接释放

要点

  • tcp是双向的,所以主动断开方,只是关闭了单向发送,仍可以接收数据,所以需要4次通信才能完成完全关闭

为什么需要主动关闭方需要等待2MSL,有个TIME_WAIT状态?

  1. 确保A(主动关闭方)发送的最后一个ACK报文(针对B发过来的断开连接请求的响应)可以被B收到

  2. 确保整个通信链路中的已失效的连接请求报文已经被处理,保证后续新的TCP连接逻辑正常

阅读此文

2016-03-11
获取errno宏定义

cpp -dM /usr/include/errno.h | grep 'define E' | sort -n -k 3

参考

  1. http://stackoverflow.com/questions/503878/how-to-know-what-the-errno-means
阅读此文

2016-03-11
tcp-accept

1
2
int accept(int socket, struct sockaddr *restrict address,
socklen_t *restrict address_len)
;

要点

  • address_len为传入传出参数!

  • 当监听套接字设置为非阻塞时,若accept未获取到连接,则不阻塞,返回失败,errno设置为EAGAINEWOULDBLOCK

错误代码

  • EMFILE 打开的文件超过限制
阅读此文

2016-03-10
修改limit

  1. /etc/security/limits.conf

    * hard nofile 10000
    
阅读此文

2016-03-10
线程

出发点

  1. 提高资源利用率

  2. 提高系统吞吐量

  3. 降低编程复杂性

使用线程的好处

  1. 单独的线程去处理某种事件,简化异步事件的代码,如服务端采用一对一的线程去处理IO事件

  2. 相比多进程,更加容易进行数据共享

  3. 将问题分解,改善程序的吞吐量。

    在单线程的情况下,任务是串行化执行的,根据任务本身地的特点,分解成多个步骤,并行

  4. 对于交互程序,改善响应时间

  5. 相对于多进程,开销更小

要点

  1. 线程标识采用pthread_t,底层类型取决于实现,相等判断需要使用pthread_equal

  2. 创建新线程后,与主线程的调用顺序依赖于OS的线程实现和调度算法

  3. 在pthread(NTPL)实现中,默认栈大小为8M,可通过如下方式查询:

    • ulimit -s

    • getrlimit

    • pthread_attr_getstacksize

阅读此文

2016-03-09
poll

API

1
2
3
4
5
6
7
8
9
#include <poll.h>

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

struct pollfd {
int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};
  • 用户层通过pollfd数组,来管理需要监控描述符IO事件,具体数量由用户控制

对比select

存储描述符和对应监听事件的数据结构不同

  • 描述符大小不受限制
阅读此文

2016-03-09
IO模型

分类

  • 阻塞IO

  • 非阻塞IO

  • IO复用(select,poll,epoll)

  • 信号驱动IO

  • 异步IO

阅读此文

2016-03-08
proactor

与Reactor模型相对应,Proactor最大的特点是使用异步I/O。所有的I/O操作都交由系统提供的异步I/O接口去执行。Proactor多路复用器等待异步I/O完成,并调用相应的用户处理函数。为了对比Reactor模型,以一个read操作为例:

在Reactor中:

  • 将要读的文件描述符注册到多路复用器中。
  • 多路复用器等待上述描述符的可读事件以及其它所有已经注册过的事件。
  • 描述符变成可读之后,多路复用器返回,并调用用户提供的处理函数,开始读文件操作。

在Proactor中:

  • 用户函数启动一个异步读文件的操作。同时将这个操作注册到多路复用器上。多路复用器并不关心文件是否可读而是关心这个异步读操作是否完成。
  • 异步读文件是操作系统完成,用户程序不需要关心。多路复用器等待直到有完成通知到来。
  • 当操作系统完成了读文件操作——将读到的数据复制到了用户先前提供的缓冲区之后,通知多路复用器读操作已完成。
  • 多路复用器再调用相应的处理程序,处理数据。
阅读此文

2016-03-08
reactor

将所有要处理的I/O事件注册到一个中心I/O多路复用器上,同时主线程阻塞在多路复用器上;一旦有I/O事件到来或是准备就绪(区别在于多路复用器是边沿触发还是水平触发),多路复用器返回并将相应I/O事件分发到对应的处理器中。

这里有三个重要的组件:

  • 多路复用器:由操作系统提供,在linux上一般是select, poll, epoll等系统调用。
  • 事件分发器:将多路复用器中返回的就绪事件分到对应的处理函数中。
  • 事件处理器:负责处理特定事件的处理函数。

核心要点

  • 监听的是IO就绪事件(proactor监听的是IO完成事件)
阅读此文

2016-03-08
IO复用

所谓的IO复用意思是指复用一个线程来处理多个对象的IO

阅读此文