4.服务器并发

本文围绕服务器并发展开,介绍了 TCP 通信中服务器与多客户端连接的情况。单线程/单进程场景下服务器无法处理多连接,有多种解决方案。还分别阐述了多进程并发和多线程并发服务器程序的设计,包括进程和线程的角色分配、资源使用及处理细节等。
4.1 单线程 / 进程

在 TCP 通信过程中,服务器端启动之后可以同时和多个客户端建立连接,并进行网络通信

在单线程 / 单进程场景下,服务器是无法处理多连接的,解决方案也有很多,常用的有三种:

使用多线程实现 使用多进程实现 使用 IO 多路转接(复用)实现 使用 IO 多路转接 + 多线程实现

4.2 多进程并发

如果要编写多进程版的并发服务器程序,首先要考虑,创建出的多个进程都是什么角色,这样就可以在程序中对号入座了。在 Tcp 服务器端一共有两个角色,分别是:监听和通信,监听是一个持续的动作,如果有新连接就建立连接,如果没有新连接就阻塞。关于通信是需要和多个客户端同时进行的,因此需要多个进程,这样才能达到互不影响的效果。进程也有两大类:父进程和子进程,通过分析我们可以这样分配进程:

  • 父进程:

    • 负责监听,处理客户端的连接请求,也就是在父进程中循环调用 accept() 函数

    • 创建子进程:建立一个新的连接,就创建一个新的子进程,让这个子进程和对应的客户端通信

    • 回收子进程资源:子进程退出回收其内核 PCB 资源,防止出现僵尸进程

  • 子进程:负责通信,基于父进程建立新连接之后得到的文件描述符,和对应的客户端完成数据的接收和发送。

    • 发送数据:send() / write()

    • 接收数据:recv() / read()

在多进程版的服务器端程序中,多个进程是有血缘关系,对应有血缘关系的进程来说,还需要想明白他们有哪些资源是可以被继承的,哪些资源是独占的,以及一些其他细节:

  • 子进程是父进程的拷贝,在子进程的内核区 PCB 中,文件描述符也是可以被拷贝的,因此在父进程可以使用的文件描述符在子进程中也有一份,并且可以使用它们做和父进程一样的事情。

  • 父子进程有用各自的独立的虚拟地址空间,因此所有的资源都是独占的

  • 为了节省系统资源,对于只有在父进程才能用到的资源,可以在子进程中将其释放掉,父进程亦如此。

  • 由于需要在父进程中做 accept() 操作,并且要释放子进程资源,如果想要更高效一下可以使用信号的方式处理

4.3 多线程并发

编写多线程版的并发服务器程序和多进程思路差不多,考虑明白了对号入座即可。多线程中的线程有两大类:主线程(父线程)和子线程,他们分别要在服务器端处理监听和通信流程。根据多进程的处理思路,就可以这样设计了:

  • 主线程:

    • 负责监听,处理客户端的连接请求,也就是在父进程中循环调用 accept() 函数

    • 创建子线程:建立一个新的连接,就创建一个新的子进程,让这个子进程和对应的客户端通信

    • 回收子线程资源:由于回收需要调用阻塞函数,这样就会影响 accept(),直接做线程分离即可。

  • 子线程:负责通信,基于主线程建立新连接之后得到的文件描述符,和对应的客户端完成数据的接收和发送。

    • 发送数据:send() / write()

    • 接收数据:recv() / read()

在多线程版的服务器端程序中,多个线程共用同一个地址空间,有些数据是共享的,有些数据的独占的,下面来分析一些其中的一些细节:

  • 同一地址空间中的多个线程的栈空间是独占的

  • 多个线程共享全局数据区,堆区,以及内核区的文件描述符等资源,因此需要注意数据覆盖问题,并且在多个线程访问共享资源的时候,还需要进行线程同步。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值