`
memorymyann
  • 浏览: 267402 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

7.并发服务器 以及 与之对应的客户端2

阅读更多

之前程序存在着一个不确定性的因素。之前服务器代码中。子进程在死亡后,会向父进程发送SIGCHLD信号。这个信号会被父进程捕获,然后父进程调用wait函数对死亡子进程处理防止其变成僵尸进程(僵尸进程会一直占用内存资源在它被回收之前。如果父进程在死亡之前没有回收僵尸进程,那么在unix下,僵尸进程会被init进程托管并回收。无主进程都会被托管给init)。

 

执行之前的代码,然后执行ps -aux可以看到不会有服务器派生的子进程成为僵死进程,但如果将客户端代码改成

[root@liumengli net]# cat echo_client2.c
#include "/programe/net/head.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

int main(int argc, char ** argv) {
        int sockfd[5], i;
        struct sockaddr_in serv_socket;

        for(i = 0; i < 5; i++) {
                sockfd[i] = socket(AF_INET, SOCK_STREAM, 0);
                bzero(&serv_socket, sizeof(serv_socket));
                serv_socket.sin_family = AF_INET;
                serv_socket.sin_port = htons(atoi(argv[1]));
                inet_pton(AF_INET, "192.168.1.235", &serv_socket.sin_addr);
                connect(sockfd[i], (struct sockaddr *)&serv_socket, sizeof(serv_socket));
        }
        getchar();
        exit(0);
}

 

这个代码也很简单,只是一次对服务器进行了5次链接,而由此导致服务器会产生5个子进程为其服务,当我们在客户端按下回车,终止客户端进程后。再到服务器上输入ps -aux会看到有4个僵尸进程(一般是4个)。产生的原因是因为:unix不会对信号排队。

 

所谓信号不排队,在这里是指,当子进程SIGHCLD到达时,父进程开始响应这个信号,并作出处理。同时会关闭对SIGCHLD的响应,在处理过程中到达的SIGHCLD信号不会被响应,但也不会排队等待,信号会被丢失。

 

之前5个SIGCHLD信号几乎是同时到达,其中之一个被响应,而其它信号则会丢失,从而导致只调用了一次处理函数,剩下的进程就会变成僵尸进程。

 

要想解决这个问题,首先要看wait函数和waitpid这2者之间的区别。(当然也可以从信号不排队处着手,但这貌似难度很大)。

 

pid_t wait(int * statloc)

返回终止进程的pid和状态,状态存在于statloc中,可以通过sys/wait.h定义的宏操作获取。当父进程调用wait时候,如果所有的子进程都在运行,则父进程会被阻塞(当然,这里我们是在收到SIGCHLD信号后才调用,所以不会被阻塞)。如果没有子进程则wait会出错并立即返回。

我们再次分析之前的服务器情况,当子进程SIGCHLD信号到达时候,父进程开始调用my_op函数开始处理僵尸子进程。但此时共有5个子进程死亡,并有5个SIGCHLD到达,其它4个信号丢失,wait只是处理其中一个子进程从而有4个僵尸进程遗留。

 

当我们采用waitpid则可以用适当的手段解决这类问题。

pid_t waitpid(pid_t pid,  int * statloc, int options)

返回终止的子进程的pid。参数pid == -1时候等待任意子进程,pid > 0或pid < 0等待与pid绝对值相同的子进程。pid == 0等待其组ID和调用者组ID相同的任一进程。statloc同上。options ==  WNOHANG若由PID等待的子进程并不立即可用,waitpid不等待,立即返回0.另一个不多做解释。

 

当我们把my_op函数改成

void my_op(int signum, siginfo_t * info, void * myact) {
        pid_t pid;
        int stat;

        while((pid = waitpid(-1, &stat, WNOHANG)) > 0)
                printf("child %d terminated\n", pid);

        return;
}

就可以有效避免因信号不排队到导致的某些僵尸子进程无法回收的不可预料因素。当然信号丢失的情况仍在发生,但我们关心的是僵尸子进程的回收,这里只是通过其它办法回收了僵尸子进程。

分析这段函数,当这个函数被调用时候,也就是收到了SIGCHLD信号,也就是有子进程死亡。不管是多个还是1个信号到达。执行到循环体,就会将所有僵尸子进程回收后,退出。当然,极端情况当循环体执行完后,所有僵尸进程回收结束,进入return时候,此时也有可能有SIGCHLD到达,这并不要紧,因为即使这次没有回收,等下次有子进程发出SIGCHLD信号时,上次遗留的依然会被清除。

 

其实此时服务器代码还可以改成,不加载信号处理代码,直接将循环体写到创建子进程的循环内部,当然不能写到子进程代码里面。当然此时,所有子进程死亡不会引起waitpid被调用,而是当下次子进程创建时候,遇到这段代码,则上次死亡的僵尸进程会被回收。这种方式没有加载信号处理的方式有效。

分享到:
评论

相关推荐

    LINUX环境并发服务器的实现模型

    在网络程序里面,一般来说都是许多客户对应一个服务器,为了处理客户的请求,对服务端的程序就提出了特殊的要求。 目前最常用的服务器模型有: ...•并发服务器:服务器在同一时刻可以响应多个客户端的请求

    iocp 服务端/客服端 大并发访问 上万 源码与文档

    IOCP服务器压力测试 运行以后可以看到IOCP服务器和其他模型的性能差距,还真是不看不知道呢!内附测试程序实现源码,具有重要参考意义

    基于Akka的高性能可伸缩的JAVA网络游戏服务器 简单的单服务器开发与集群开发的切换 使用Actor处理高并发 易于测试

    服务器从客户端收到消息,让后可以根据消息的定义处理对应的逻辑。 我们在这样的模式下开发建议不要建立全局的管理器。注意Actor模式下,每个玩家都是独立的Actor。 处理消息的时候,对于自己的数据更改是线程安全的...

    精通websphere MQ

    目录.................................................................................................................................2 内容提要...........................................................

    高并发数据库设计.pdf

    ⾼并发数据库设计 随着乐视硬件抢购的不断升级,乐视集团⽀付⾯临的请求压⼒百倍乃⾄千倍的暴增。作为商品购买的最后⼀环,保证⽤户快速稳定的完成⽀ 付尤为重要。所以在15年11⽉,我们对整个⽀付系统进⾏了全⾯的...

    基于Linux C++和socket网络编程的即时通信系统源码+项目说明(课程设计).zip

    服务端:能够接受新的客户连接,并将每个客户端发来的信息,广播给对应的目标客户端 2.客户端:能够连接服务器,并向服务器发送消息,同时可以接受服务器发来的消息 服务端: 1.支持多个客户端接入,实现聊天室...

    Qt编写网络调试助手(TCP客户端+TCP服务端+UDP服务端)终极版.zip

    时隔半年,对网络调试助手工具进行所有代码重写,这次目录结果整齐的一逼,代码整齐的一逼,非常完善了...7:支持多个客户端连接并发。 8:采用单线程。 9:四种模式,tcp服务器、tcp客户端、udp服务器、udp客户端。

    Qt编写网络调试助手(TCP客户端+TCP服务端+UDP服务端)终极版

    时隔半年,对网络调试助手工具进行所有代码重写,这次目录结果整齐的一逼,代码整齐的一逼,非常完善了,...7:支持多个客户端连接并发。 8:采用单线程。 9:四种模式,tcp服务器、tcp客户端、udp服务器、udp客户端。

    公司网络通信系统源码+毕业论文

    在面对几百个甚至更多的客户端同时发出连接信息的情况下,服务器要求能够保持高性能的并发处理机制,迅速地完成这几百个并发请求的处理和发送任务。 在扩展性和伸缩性方面,聊天系统也提出了一定的要求。当一台...

    Java并发编程(学习笔记).xmind

    (3)简化异步事件的处理:服务器应用程序在接受来自多个远程客户端的请求时,如果为每个连接都分配一个线程并且使用同步IO,就会降低开发难度 (4)用户界面具备更短的响应时间:现代GUI框架中大都使用一个...

    NetTool.rar

    基本功能: 1:16进制数据和ASCII数据收发。 2:定时器自动发送。 3:自动从配置文件加载最后一次的界面... 7:支持多个客户端连接并发。 8:采用单线程。 9:四种模式,tcp服务器、tcp客户端、udp服务器、udp客户端。

    Android移动开发-使用HttpURLConnection实现多线程的下载

    假设服务器同时最多服务100个用户,在服务器中一条线程对应一个用户,100条线程在计算机内并发执行,也就是有CPU划分时间片轮流执行,如果A应用使用了99条线程下载文件,那么相当于占用了99个用户的资源,自然就拥有...

    勤哲excel服务器2010教程

    目 录 基础教程 2 第1章、 Excel服务器概述 3 1.1 Excel服务器是信息系统工具 3 1.2 用Excel服务器构建信息系统 3 1.3 基于Excel服务器的信息系统架构 8 1.4 如何学习使用Excel...24.4.2 系统使用 410 24.5 VBA接口 412

    DNS实验报告.pdf

    (1)多客户端并发 允许多个客户端(可能会位于不同的多个计算机)的并发查询,即:允许第一个 查询尚未得到答案前就启动处理另外一个客户端查询请求(DNS 协议头中 ID 字 段的作用) 超时处理 (2)由于 ...

    OA系统设计方案(1).doc

    ORACLE10I 中间件:Tomcat、Jboss 通信协议:http 客户端浏览器:IE9 2 开发环境 1 硬件环境 1) 应用服务器: 2) 数据库服务器: 2 软件环境 1) 操作系统:Win2003、Win7 2) 数据库系统:ORACLE10I 3) 开发平台及工具...

    IIS6.0 IIS,互联网信息服务

    以及引入了命令行工具 Appcmd.exe ,给 Web 服务器的日常管理、监视和配置提供了除图形接口外的另一种方式,更为简单、高效。 同Windows XP一样,在Windows Vista的默认设置下,IIS (Internet 信息服务) 7.0未予安装...

    7kbscan-WebPathBrute v1.6.0 最新编译版

    扫描类型 分别对应同目录下多个txt文件 自定义对应的文件是custom.txt,后缀格式为".xxx",如不需要后缀可以不填 直接将字典内容修改为"111.svn"此类即可。 状态码我也不多解释了 双击表格内某行即调用系统默认...

    JMeter操作手册大全.docx

    一般情况下,性能测试是将系统处理能力容量测出来,而不是测试并发用户数,除了服务器长连接可能影响并发用户数外,系统处理能力不完全受并发用户数影响,可以用最小的用户数将系统处理能力容量测试出来,也可以用更...

    JAVA局域网飞鸽传书软件设计与实现(源代码+论文).zip

    该压缩包包含JAVA局域网飞鸽传书软件的设计与实现部分,以及对应的源代码和论文。该软件旨在提供一种便捷快速的局域网文件传输方式,用户可以在局域网内快速地传输文件。 ## 功能介绍 该软件具有以下主要功能: -...

    基于C++实现多线程连接池MySQL源码+项目说明+详细代码注释.zip

    连接池主要用于`网络服务器端`,用于同时接受`多个用户端`请求,数据库与数据库客户端采用`TCP通信`. * 数据库客户端和服务端先建立起`多个连接` * 多线程通过`套接字通信`取出连接池中的一个连接,然后和服务器...

Global site tag (gtag.js) - Google Analytics