服务器并发性处理
方式:
1. 多进程模型
2. 多线程模型
3. IO多路转换
1. 多进程模型:
父进程循环调用accept来接受客服端的连接,当有客户端连接上来时,就调用fork函数创建子进程来与客户端对接。
如果不创建子进程,那么父进程调用read函数就可能阻塞,就不能实现并发性的处理了。
2. 多线程模型:
多线程和多进程并发处理模型类似,主线程也是循环调用accept来接受客服端的连接,有客户端连上来时,主线程创建一个子线程来与客户端对接
注意:要设置线程分离属性,这样子线程退出时会自动回收系统资源
3. IO多路转换(IO多路复用)
a. fcntl函数实现(非阻塞方式):
前面的多线程模型和多进程模型进行并发处理都是阻塞性的读写,如果某个客户端没有发送数据,那么和这个客户端对接的子进程/子线程将阻塞,这就会占用系统资源
实现思路:
主控线程会不断循环调用accept函数,当有客户端连接上来,就将返回的socket描述符放到一个动态数组中。
子线程负责遍历数组中的描述符,并通过这个fd和对应的客户端进行双向的通信(注意:这里是采用非阻塞的read/write),如果读不到客户端的数据,就进行下一个,如果读的到,就将读到的数据处理,在遍历下一个。
b. select函数实现:
实现思路:
主控线程会不断循环调用accept函数接受客户端的连接,当有客户端连接上来,就将返回的socket描述符放到一个动态数组中。
子线程构建描述符集(select函数会用到描述符集),调用select函数委托内核去检查传入的描述符是否准备好(即可以使用),根据返回的准备好的描述符(要用FD_LSSET来检测,来确定这个准备好的描述符)。
找到准备好的描述符就可以进行IO(read/write)操作(对select返回的描述符读写都是非阻塞的)。