要点
- tcp是双向的,所以主动断开方,只是关闭了单向发送,仍可以接收数据,所以需要4次通信才能完成完全关闭
为什么需要主动关闭方需要等待2MSL,有个TIME_WAIT
状态?
确保A(主动关闭方)发送的最后一个ACK报文(针对B发过来的断开连接请求的响应)可以被B收到
确保整个通信链路中的已失效的连接请求报文已经被处理,保证后续新的TCP连接逻辑正常
TIME_WAIT
状态?确保A(主动关闭方)发送的最后一个ACK报文(针对B发过来的断开连接请求的响应)可以被B收到
确保整个通信链路中的已失效的连接请求报文已经被处理,保证后续新的TCP连接逻辑正常
1 | int accept(int socket, struct sockaddr *restrict address, |
address_len
为传入传出参数!
当监听套接字设置为非阻塞时,若accept
未获取到连接,则不阻塞,返回失败,errno
设置为EAGAIN
或EWOULDBLOCK
EMFILE
打开的文件超过限制/etc/security/limits.conf
* hard nofile 10000
提高资源利用率
提高系统吞吐量
降低编程复杂性
单独的线程去处理某种事件,简化异步事件的代码,如服务端采用一对一的线程去处理IO事件
相比多进程,更加容易进行数据共享
将问题分解,改善程序的吞吐量。
在单线程的情况下,任务是串行化执行的,根据任务本身地的特点,分解成多个步骤,并行
对于交互程序,改善响应时间
相对于多进程,开销更小
线程标识采用pthread_t
,底层类型取决于实现,相等判断需要使用pthread_equal
创建新线程后,与主线程的调用顺序依赖于OS的线程实现和调度算法
在pthread(NTPL)实现中,默认栈大小为8M,可通过如下方式查询:
ulimit -s
getrlimit
pthread_attr_getstacksize
1 |
|
pollfd
数组,来管理需要监控描述符IO事件,具体数量由用户控制存储描述符和对应监听事件的数据结构不同
与Reactor模型相对应,Proactor最大的特点是使用异步I/O。所有的I/O操作都交由系统提供的异步I/O接口去执行。Proactor多路复用器等待异步I/O完成,并调用相应的用户处理函数。为了对比Reactor模型,以一个read操作为例:
在Reactor中:
在Proactor中:
将所有要处理的I/O事件注册到一个中心I/O多路复用器上,同时主线程阻塞在多路复用器上;一旦有I/O事件到来或是准备就绪(区别在于多路复用器是边沿触发还是水平触发),多路复用器返回并将相应I/O事件分发到对应的处理器中。
这里有三个重要的组件:
所谓的IO复用意思是指复用一个线程来处理多个对象的IO