一、服务器模型
1. 单循环服务器:
单循环服务器在同一时刻只能处理一个客户端的请求。由于其结构简单,适合低负载的场景,但在并发请求增加时可能导致性能问题。
2. 并发服务器模型:
并发服务器可以同时响应多个客户端请求,常见的实现方式包括:
1.多进程:为每个连接创建一个新的子进程。
2.多线程:为每个连接创建一个新的线程。
3.IO多路复用:通过非阻塞IO和信号处理技术,允许一个线程或进程管理多个连接。
二、 Linux系统IO模型
1. 阻塞IO:
出现情况:当使用`scanf`、`getchar`等函数时。调用如`read`、`recv`等时,线程会阻塞,直到数据可用。这种方式可以实现多任务同步,节省CPU资源,提高执行效率。
2. 非阻塞IO:
- 通过`fcntl`等函数设置文件描述符为非阻塞模式。
- 可以在等待数据的同时处理其他任务,但可能会浪费CPU资源,因为需要频繁检查是否有数据可用。
3. 信号驱动IO:
- 利用信号机制实现异步IO,通过`O_ASYNC`设置文件描述符的信号驱动属性。
- 当有IO事件发生时,内核会产生信号,线程可以处理信号,但此方法通常只适用于少量IO事件的场景。
4. 多路复用IO:
-IO多路复用是指通过单个线程同时监视多个IO流(如文件描述符、套接字)的状态,进程可以通过一个调用(如select
或poll
)来等待一个或多个IO操作的准备状态。
-特点:高效性:通过单个或少数线程处理多个连接或文件描述符,节省了上下文切换的开销,提高了性能。灵活性:IO多路复用提供了一个统一的接口,允许程序员在多个IO操作间进行调度
三、函数接口
`fcntl`
用于设置或获取文件描述符的属性。
int fcntl(int fd, int cmd, ... /* arg */ );
参数说明:
- `fd`:文件描述符
- `cmd`:
- `F_GETFL`:获取文件描述符的属性
- `F_SETFL`:设置文件描述符的属性
返回值:
- `F_GETFL`成功返回当前属性,失败返回-1。
- `F_SETFL`成功返回0,失败返回-1。
常用标志:
- `O_NONBLOCK`:设置为非阻塞模式。
- `O_ASYNC`:设置为异步模式。
四、总结
- 阻塞IO适合对响应时间和并发性要求不高的情境,而非阻塞IO则适合高并发和实时性的需求。根据具体应用场景,开发者可以选择合适的IO模型来实现最佳的性能和用户体验。
- 信号驱动IO适合需要及时响应IO操作的场景,而IO多路复用则适合高并发处理多个IO流的场景。两者在性能和复杂性上各有优缺点,开发者根据具体需求选择最合适的方法。