循环和并发服务器比较
优化代码性能与减少资源消耗的技巧

优化代码性能与减少资源消耗的技巧优化代码性能和减少资源消耗是编程中非常重要的课题。
通过优化代码,我们可以提高程序的运行效率,减少内存占用和CPU利用率,从而提升用户体验,降低服务器负载等。
下面我将分享一些优化代码性能和减少资源消耗的技巧,供大家参考:1.使用合适的数据结构:选择合适的数据结构能够提高代码的性能。
例如,如果需要频繁地搜索数据,可以使用散列表(哈希表)来存储数据,以提高查找效率;如果需要按顺序访问数据,可以使用链表或数组。
2.减少内存分配:内存分配是一项耗时的操作,频繁的内存分配会导致性能下降。
可以采取以下措施来减少内存分配:-尽量使用对象池和缓存池来重复利用已分配的内存,而不是每次使用都分配新的内存。
-注意使用StringBuilder等可变对象,避免频繁的字符串连接操作。
-预分配足够大的内存空间,以避免频繁的内存重新分配。
当然,如果内存空间过大又用不完,也浪费了资源。
3.避免频繁的IO操作:IO操作是相对较慢的,频繁的IO操作会拖慢程序的运行速度。
可以采取以下措施来避免频繁的IO操作:-尽量采用批处理的方式进行IO操作,减少单次IO操作的次数。
-使用缓冲IO流来减少IO操作频率,一次读写多个数据。
4.使用适当的算法和数据结构:选择合适的算法和数据结构可以大大提高代码的性能。
例如,排序算法的选择、查找算法的选择等。
同时,可以使用适当的数据结构来提高代码的性能,例如使用哈希表可以快速查找数据,使用二叉堆可以快速获取最小/最大值。
5.减少循环嵌套和递归:循环嵌套和递归都会消耗大量的资源。
可以尽量避免多层循环嵌套和深层次的递归调用,或者考虑使用尾递归等优化方式。
6.并行和并发处理:合理的并行和并发处理可以充分利用多核CPU 的优势,提高代码的运行效率。
可以使用线程池、并行计算库等来实现并行和并发处理。
7.减少系统调用次数:系统调用是相对较慢的操作,频繁的系统调用会拖慢程序的运行速度。
可以考虑合并多次系统调用,或者使用合适的系统调用方式,以提高代码的性能。
TCP IP课程复习题+部分答案(修改版)

2015年TCP/IP网络编程复习题一、选择题1、要对IP协议直接访问,必须使用()套接字①数据流②数据报③原始④没有办法2、下列套接字函数可产生套接字的是()①send ②accept ③connect ④close3、使用数据报套接字进行网络通信的应用层协议是()①FTP ②POP3 ③PPP ④SNMP4、要建立数据报套接字,在socket函数中需要使用的参数是()。
① SOCK_DGRAM②SOCK_STREAM ③ SOCK_RAM ④SOCK_PACKET5、下面的属于IPv4地址结构的是()。
① sockaddr_in ②sockaddr ③ addr ④in_addr6、初始化信号量应该使用的函数名是()。
① pthread_cond_init ②pthread_create ③ sem_init ④pthread_mutex_init7、下列哪个协议是应用层的()①IGMP ②HTTP ③ARP ④ICMP8、下列哪个协议是应用层的()①CSMA ②SMTP③TCP ④ICMP9、在Linux下,下列哪个函数用来关闭一个套接字()①closesocket,②WSACleanup ③close④exit10、在数据流式套接字中()套接字函数将产生网络报文① socket ②bind ③ sendto ④connect11、下列套接字函数中,不能用于数据流通信的是()①socket ②bind ③ send ④recvfrom12、下列套接字函数中,需要地址结构作为参数的是()①socket ②recvfrom ③ send ④close13、 listen函数的作用是()①接受连接请求②设置等待连接状态③连接套接字到目的地④指定本地地址14、 winsock中提供的用于消息机制的函数是()①WSAStartup ② WSAEventSelect ③WSACleanup ④WSAAsynSelect15、将长整形数值从网络顺序转换为本机顺序的函数( )①ntohl ② htons ③ htonl ④ ntohs16、下列哪个函数在linux系统下网络程序不能使用( )①closesocket ② select ③close ④ printf17、套接字函数在完成其任务之前不返回,我们称之为()①消息机制②事件机制③阻塞方式④非阻塞方式18、属于网络层的协议()① CSMA/CD ② ICMP ③ FTP ④ UDP19、属于链路层的协议()① CDMA ② ICMP ③ PPP ④ UDP20、下列应用中使用TCP传输的是()①实时视频② IP电话③网页传输④ DNS21、下列应用中使用UDP传输的是()①文件传输② IP电话③网页传输④电子邮件22、 IP协议具有如下哪个特点()①保证传输可靠性②无连接的数据报③建立虚电路④进行拥塞控制23、下列哪个特点是TCP协议没有的()①保证传输可靠性②流量控制③建立虚电路④进行拥塞控制24 在网络通信中,客户机要访问服务器程序,必须知道服务器的()①地理位置②程序名称③所在国家④端口和主机地址25、下列哪个套接字函数不能用于客户程序()①socket ②send ③accept ④ connect26、下列哪个套接字函数不能用于服务器程序()①socket ②sendto ③accept ④ connect27、下列哪个套接字函数不能用于服务器程序()①listen ②send ③accept ④ connect28、网络应用程序运行在网络系统的()上①端系统②核心系统③路由器④网线29、下列设施属于网络核心系统的是()①路由器②智能手机③Web服务器④ PC30、根据规定,网络字节序是()①Big endian ② Little endian ③和Intel x86一致④说不清31、浏览器是一种()①HTTP客户端②HTTP服务器③文件服务器④邮件客户端32、已知IP地址的点分十进制形式,下列哪个函数能够得到其整数形式()①gethostbyname ②inet_ntoa ③inet_addr ④gethostbyaddr二、判断题1.服务器必须先于客户端启动。
性能测试线程组和并发数的设置

性能测试线程组和并发数的设置
在性能测试中,线程组和并发数的设置是非常重要的。
下面是一些常见的设置方法:
1. 确定目标:首先要明确测试的目标,例如要测量系统的吞吐量、响应时间或并发用户数。
2. 确定线程组:根据目标和业务需求,确定需要模拟的线程组。
线程组代表了一组并发用户,可以根据实际情况设置多个线程组。
3. 设置线程数:根据并发用户数目标,确定每个线程组中的线程数。
可以根据系统的负载能力和硬件性能进行调整,一般建议起始设置一个较小的值,然后逐渐逼近目标并监测系统性能。
4. 设置启动时间和延迟时间:可以设置线程组的启动时间和每个线程之间的延迟时间,以模拟真实的用户行为。
5. 设置循环次数:可以设置每个线程的循环次数,或者根据业务场景设置循环控制器。
6. 分配资源:根据测试需求,可以设置线程组的共享资源、COOKIE、缓存等。
7. 监测和分析:进行性能测试时,建议同时监测服务器的 CPU 使用率、内存占用、网络带宽和响应时间等指标,以及对测试结果进行分析和优化。
请注意,以上回答仅针对性能测试线程组和并发数设置的一般性建议。
具体的设置还需要根据实际业务场景和系统特点进行调整。
jmeter 并发原理

jmeter 并发原理JMeter并发原理JMeter是一款广泛使用的性能测试工具,它可以模拟多个用户同时访问目标服务器,并且可以根据预先设定的参数对服务器的性能进行评估。
在使用JMeter进行并发测试时,需要了解其并发原理。
并发测试是指在同一时间段内模拟多个用户同时访问服务器,以测试服务器在高负载情况下的性能表现。
在JMeter中,可以通过线程组来模拟多个用户,每个线程代表一个用户,并发测试就是通过同时启动多个线程来模拟多个用户同时访问服务器。
在进行并发测试时,需要设置线程数和循环次数。
线程数表示同时模拟的用户数,循环次数表示每个用户的访问次数。
通过调整线程数和循环次数,可以模拟不同负载下的情况,从而评估服务器在不同负载下的性能表现。
JMeter的并发原理可以分为以下几个方面:1. 线程控制器:线程控制器是JMeter中的一个重要组件,它可以控制线程的启动、停止和循环次数等。
在并发测试中,可以通过线程控制器来控制多个线程的并发访问。
2. 断言:断言是用来验证服务器返回结果的正确性的。
在并发测试中,可以通过断言来验证每个线程的访问结果是否正确,从而保证测试的准确性。
3. 监视器:监视器可以实时监测服务器的性能指标,如响应时间、吞吐量等。
在并发测试中,可以通过监视器来监测服务器在不同负载下的性能表现。
4. 结果树:结果树可以保存测试结果,包括每个请求的响应时间、吞吐量等。
在并发测试中,可以通过结果树来分析每个线程的访问情况,从而评估服务器的性能表现。
5. 参数化:参数化可以根据预先设定的参数来模拟不同用户的行为。
在并发测试中,可以通过参数化来模拟多个用户的不同访问行为,从而更加真实地模拟实际情况。
6. 分布式测试:JMeter支持分布式测试,可以将不同的线程组部署在不同的机器上,通过网络连接进行并发测试。
在并发测试中,可以通过分布式测试来模拟更大规模的负载,从而评估服务器的承载能力。
通过以上几个方面的原理,可以实现在JMeter中进行并发测试。
高并发应用服务器的性能优化

高并发应用服务器的性能优化一、高并发应用服务器的定义随着互联网的发展,如今的应用服务器面对的用户量越来越大,高并发应用服务器出现在了用户面前。
所谓高并发应用服务器,是指在同一时间内,服务器处理的请求数量非常庞大,同时要求处理速度很快,保证服务器的稳定性和用户的体验。
二、高并发应用服务器性能瓶颈分析1、CPU:服务器的CPU是高并发应用运行的核心,每个请求都需要CPU的处理。
如果CPU性能过低,就会影响并发请求的处理速度。
2、内存:高并发应用需要大量的内存支撑,如果内存空间不足,就会导致服务器崩溃或者出现其他问题。
3、磁盘IO:服务器中的数据存储在磁盘里,所以磁盘IO也是影响高并发服务器性能的关键因素。
如果磁盘IO过慢,将会导致请求的响应时间过长。
4、网络带宽:高并发应用所处理的请求流量较大,网络带宽会成为一个瓶颈,当网络带宽不足时,请求响应时间也会变得很长。
5、并发连接数:如果并发连接数过高,将会导致系统负载过大或者短暂停机,从而严重影响用户的体验。
6、代码质量:应用的代码质量也是一个重要因素,重复的代码或者死循环等问题会严重影响并发处理性能。
三、高并发应用服务器的性能优化1、优化CPU:提高CPU的主频,增加CPU数量,优化系统调度算法,这些都是提高CPU性能的方法。
2、优化内存:增加内存空间,释放不必要特定可用的内存,将频繁使用的数据存放在内存中等,都能够优化服务器的内存性能。
3、优化磁盘IO:使用高速磁盘,创建RAID磁盘数组,缓存磁盘读写操作等,都能够优化服务器的磁盘IO性能。
4、优化网络带宽:使用CDN服务、对静态资源进行缓存、减少请求次数等方法都能够减轻服务器的负担,优化网络带宽。
5、增加服务器数量:通过新增服务器的方式来增加系统容量,通过负载均衡,将请求分配到不同的服务器上,可以保证并发连接数不过高,从而实现高并发性能的优化。
6、优化代码质量:去除重复的代码,避免死循环,使用新的算法,合理的设计数据库结构等,都能够优化代码质量,提高并发处理性能。
软件性能优化技巧

软件性能优化技巧软件性能是指在特定的硬件和软件环境中,软件系统所表现出的效率和响应速度。
优化软件性能可以提升用户体验,降低系统资源消耗,提高系统稳定性。
本文将介绍一些常用的软件性能优化技巧,帮助开发人员和系统管理员提升软件的性能表现。
1. 代码优化代码是软件的核心部分,对代码进行优化可以大大提升软件的性能。
以下是一些常用的代码优化技巧:1.1 减少函数调用函数调用的开销是比较高的,频繁的函数调用会增加系统开销。
因此,可以考虑将一些频繁调用的函数内联到调用处,减少函数调用的次数。
1.2 循环优化在循环中进行一些计算密集型的操作时,可以考虑使用位运算替代乘法、除法等操作,以减少计算开销。
另外,可以使用循环展开技术减少循环次数,优化性能。
1.3 内存管理合理使用内存,避免频繁的内存分配和释放。
可以使用对象池、缓存等技术减少内存分配的次数,提高效率。
2. 数据结构优化优化数据结构可以提升软件的性能,以下是几个常用的数据结构优化技巧:2.1 使用合适的数据结构根据具体场景的特点,选择合适的数据结构。
例如,对于频繁进行查找操作的场景,可以选择哈希表或二叉搜索树等。
2.2 数据结构压缩对于数据结构中的冗余信息,可以进行压缩以减少内存占用。
例如,可以使用位图压缩布尔类型的数据。
2.3 缓存利用在一些频繁访问的数据结构中,可以使用缓存来加速访问速度。
例如,可以缓存一些常用的计算结果,避免重复计算。
3. 并发控制并发控制是指在多线程或分布式环境下,对共享资源进行访问和管理的技术。
以下是一些常用的并发控制技巧:3.1 锁的合理使用合理使用锁可以避免数据竞争和死锁等问题。
对于频繁访问的共享资源,可以考虑将其作为粒度更小的锁的对象,提高并发性能。
3.2 无锁数据结构无锁数据结构可以提高并发性能,避免锁带来的开销。
例如,可以使用无锁队列、无锁哈希表等数据结构。
3.3 并发安全算法在某些场景下,可以使用并发安全算法来替代传统的同步机制。
服务器并发处理能力

服务器并发处理能力服务器并发处理能力是指服务器能够同时处理多个请求或任务的能力。
随着互联网的普及和网络应用的不断发展,服务器并发处理能力成为了评判一个服务器性能的重要指标之一、在这个信息时代,用户对于服务器的响应速度和处理能力要求越来越高,因此提高服务器的并发处理能力对于保证网络系统的正常运行和提升用户体验至关重要。
首先,提高服务器并发处理能力的一个重要手段是优化系统资源的利用。
服务器系统有限的资源需要合理利用,有效地分配给不同的请求或任务。
例如,可以通过合理设置缓存系统、增加服务器的硬件设备,或者采用一些技术手段来减少服务器的负荷。
通过这些措施,可以增加服务器的处理能力,提高并发处理的效率。
其次,采用多线程或多进程技术是提高服务器并发处理能力的一种常见方法。
多线程或多进程技术可以使服务器同时处理多个请求或任务,以提高并发性能。
多线程技术可以充分利用多核处理器的优势,将不同请求或任务分配到不同的线程中进行处理,从而提高服务器的并发处理能力。
而多进程技术则可以使请求或任务独立运行在不同的进程中,避免了单进程程序因为其中一个请求或任务的错误而导致整个服务器崩溃的情况。
通过合理地使用多线程或多进程技术,可以最大程度地发挥服务器的处理潜力,提高并发处理的能力。
此外,合理使用负载均衡技术也是提高服务器并发处理能力的一种有效手段。
在互联网应用中,服务器的并发处理能力通常是通过多台服务器组成的集群系统来实现的。
通过负载均衡技术,可以将请求或任务均匀地分配到集群中的不同服务器上,从而实现请求或任务的并发处理。
常见的负载均衡技术包括轮询、随机、最小连接数等。
通过合理地使用负载均衡技术,可以充分发挥集群系统的整体处理能力,提高服务器的并发处理能力。
最后,持续的系统优化和监控也是提高服务器并发处理能力的重要手段。
随着业务的不断发展和用户的不断增多,服务器的并发处理能力往往需要不断改进和优化。
因此,持续地进行系统优化和监控是非常必要的,可以根据实际情况调整服务器的配置参数,或者进行一些优化措施,以提高服务器的并发处理能力。
性能测试常用指标:响应时间,吞吐量,TPS,QPS,并发数,点击数,资源利用率,错误率

性能测试常⽤指标:响应时间,吞吐量,TPS,QPS,并发数,点击数,资源利⽤率,错误率对于性能测试,以上性能指标必须要有清楚的理解,⾃⼰总结如下:1. 响应时间(RT) 是指系统对请求作出响应的时间。
这个指标与⼈对软件性能的主观感受是⼀致的,因为它完整地记录了整个计算机系统处理请求的时间。
由于⼀个系统通常会提供许多功能,⽽不同功能的处理逻辑也千差万别,因⽽不同功能的响应时间也不尽相同,甚⾄同⼀功能在不同输⼊数据的情况下响应时间也不相同。
所以,在讨论⼀个系统的响应时间时,⼈们通常是指该系统所有功能的平均时间或者所有功能的最⼤响应时间。
当然,往往也需要对每个或每组功能讨论其平均响应时间和最⼤响应时间。
对于单机的没有并发操作的应⽤系统⽽⾔,⼈们普遍认为响应时间是⼀个合理且准确的性能指标。
需要指出的是,响应时间的绝对值并不能直接反映软件的性能的⾼低,软件性能的⾼低实际上取决于⽤户对该响应时间的接受程度。
对于⼀个游戏软件来说,响应时间⼩于100毫秒应该是不错的,响应时间在1秒左右可能属于勉强可以接受,如果响应时间达到3秒就完全难以接受了。
⽽对于编译系统来说,完整编译⼀个较⼤规模软件的源代码可能需要⼏⼗分钟甚⾄更长时间,但这些响应时间对于⽤户来说都是可以接受的。
注意: 在性能测试中, 响应时间要做更细致划分2. 吞吐量(Throughput)吞吐量是指系统在单位时间内处理完成的客户端请求的数量, 直接体现软件系统的性能承载能⼒。
这是⽬前最常⽤的性能测试指标。
对于服务器来讲,吞吐量越⾼越好.吞吐量是⼀个很宽泛的概念, 通常情况下,⽤“请求数/秒”或者“页⾯数/秒”来衡量。
体现:1. 业务⾓度: 业务数/⼩时或访问⼈数/天等2. ⽹络流量: 字节数/⼩时或字节数/天等3. 服务器性能处理能⼒(重点): TPS(每秒事务数) 和 QPS(每秒查询数):对于⽆并发的应⽤系统⽽⾔,吞吐量与响应时间成严格的反⽐关系,实际上此时吞吐量就是响应时间的倒数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
[4]C程序设计/谭浩强著.—3版.—北京:清华大学出版社,2005(2007重印)
[5] edsionte's Linuxworld|新手区/techblog/
3.2、并发服务器的应用场景及程序实例
一个典型的并发服务器程序框架:
pid_t pid;
int listenfd, connfd;
listenfd = Socket(……);
Bind(listenfd,…);
Listen(listenfd, LISTENQ);
for(;;)
{
connfd = Accept(listenfd,…);
2、循环和并发服务器的工作流程
2.1循环服务器的工作流程
面向连接的循环服务器算法
1)、创建套接字并将其绑定到它所提供服务的熟知端口上;
2)、将该端口设置为被动模式,使其准备为服务器所用;
3)、从该套接字上接收下一个连接请求,获得该连接的新的套接字;
4)、重复地读取来自客户的请求,构造响应,按照应用协议向客户发回响应;
参考文献:
[1] FreeBSD开发手册/doc/zh_CN.GB2312/books/developers-handbook/sockets-concurrent-servers.html
[2]计算机与网络/高殿武.—北京:机械工业出版社,2010.6
3.1、循环服务器的应用场景及程序实例
用于DAYTIME服务的服务器:
Int main(int argc, char *argv[])
{
Struct sockaddr_in fsin;
char*service =“daytime”;
int msock, ssock;
unsigned int alen;
if((sock = accept(msock, (struct sockaddr *) &fsin, &alen)) < 0)
errexit(“accept failed: %s\n”, strerror(errno));
TCPdaytemed(ssock);
close(ssock);
}
}
passiveTCP隐藏了很多套接字分配和绑定的细节
循环和并发服务器的比较及应用
摘要:本文阐述循环和并发服务器的工作原理,给出了循环和并发服务器的算法,从工作原理、工作流程等方面进行了阐述了两者的区别,并给出了循环和并发服务器具体程序实例代码进行分析比较两者的不同
1、循环和并发服务器的工作原理
1.1循环服务器的工作原理
循环服务器在一个时刻只处理一个请求
5)、当某个特定客户完成交互时,关闭连接,并返回步骤3以接受新的连接
无连接的循环服务器算法
1)、创建套接字并将其绑定到所提供服务的熟知端口上;
2)、重复读取来自客户的请求,构造响应,按照应用协议向客户发回响应。
2.2并发服务器的工作流程
面向连接的并发服务器算法
主1、创建套接字并将其绑定到所提供服务的熟知地址上。让该套接字保持为面向连接
QLEN:客户连接请求等待队列长度
在循环中,使用accept从主套接字得到一个连接(accept完成三次握手过程)
对于新的连接服务器调用过程TCPdaytimed进行处理
处理完毕继续循环,再次调用accept阻塞
调用TCPdaytimed返回后,主程序关闭改连接的套接字
调用close是从容关闭:TCP保证所有的数据可靠交付给客户(连接终止前收到确认)
迭代服务器比较原始,它的原型可以描述成:
while(1)
{
new_fd =服务器accept客户端的连接(
new_fd = accept(listenfd, XX, XX))
逻辑处理
在这个new_fd上给客户端发送消息
关闭new_fd
}
也就是说,这个进程是一个一个处理各个客户端发来的连接的,比如一个客户端发来一个连接,那么只要它还没有完成自己的任务,那么它就一直会占用服务器的进程直到处理完毕后服务器关闭掉这个socket。
1.2并发服务器的工作原理
不同于顺序服务器,并发服务器就要能在一个时间为多个客户端提供服务。例如,一个聊天服务器可能服务一个特定的客户端数小时──在停止为这个客户端服务之前服务器不能等待,除非是在等待一下个客户端到来之前的间隙才能等待。
我们将提供服务从守护进程移至它自己的服务进程。然而,因为每个子进程都继承所有打开的文件(套接字被像文件一样处理),新进程不仅继承“accept()返回的句柄,”那是指调用accept返回的套接字;新进程也继承顶级套接字,这是顶级进程一开始打开的套接字。
然而,服务进程不需要这个套接字,应该立即关闭(close)它。同样的,守护进程不再需要accept()返回的套接字,不仅应该,还必须关闭(close)它──否则,那迟早会耗尽可用的文件描述符。
在服务进程完成服务之后,它将关闭accept()返回的套接字。它不会返回到accept,而是退出进程。
在UNIX®上,一个进程并不真正的退出,而是返回至父进程。典型情况中,父进程等待(wait)子进程,并取得一个返回值。但是,我们的守护进程不能简单的停止或等待,那有违建立其它进程的整个目的。但是如果从不使用wait,它的子进程可能会成为僵尸──不再有功用可仍然徘徊着。
主2、反复调用recvfrom接收来自客户的下一个请求,创建一个新的从线程来处理响应
从1、从来自主进程的特定请求以及到该套接字的访问开始
从2、根据应用协议构造应答,并用sendto将该应答发回给客户
从3、退出(即:从线程处理完一个请求后就终止)
3、循环和并发服务器的应用场景及程序实例
循环服务器容易构建,但是性能差;并发服务器难以构建和设计,但是性能好
主2、将该端口设置为被动模式
主3、反复调用accept以便接收来自客户的下一个连接请求,并创建新的从线程或者进程来处理响应
从1、由主线程传递来的连接请求开始
从2、用该连接与客户进行交互;读取请求并发回响应
从3、关闭连接并退出
无连接的并发服务器算法
主1、创建套接字并将其绑定到所提供服务的熟知地址上。让该套接字保持为未连接的
if((pid = Fork()) == 0){
Close(listenfd);
doit(connfd);
Close(connfd);nnfd);
}
对TCP套接口调用close会引发一个FIN,后跟TCP连接终止序列。
为什么图中父进程connfd的close不终止它写客户的连接呢?
switch(argc)
{
case 1:
break;
case 2:
service = argv[1];
break;
default:
errexit(“usage: TCPdaytmed [port]\n”);
}
msock = passiveTCP(service, QLEN);
while(1)
{
alen = sizeof(fsin);
为了搞明白此执行过程,我们必须了解每个文件或套接口都有一个访同计数,该访同计数在文件表项中维护
,它表示当前指向该文件或套接口的打开的描述宇个数。在图中,从socket返回后,与listenfd关联的文件表项访问计数值为1,从accept返回后,与connfd关联的文件表项访问计数值也为1。但是,当fork返回后,两个描述字在父进程与子进程间共享(即复制),所以,与两个套接口相关联的文件表项访问计数值均为2。当父进程关闭connfd时,只是将访问计数值从2减为1。描述字只在访问计数值达到0时才真正关闭。
出于那样的原因,守护进程需要在初始化守护进程阶段设置信号处理程序。至少要处理信号SIGCHLD,这样守护进程可以从系统清除僵尸返回值并释放僵尸占用的系统资源。
这是现在我们的流程图包含一个进程信号框的原因,它不与任何其它框相连接。顺便说一句,许多服务器程序也处理SIGHUP,作为超级用户发出的要求重读配置文件的信号。这允许我们不必终止或重启服务器程序就改变设置。