当前位置:首页 > 日记 > 正文

Linux网络编程等的解释和waitpid()()

Linux网络编程等的解释和waitpid()()
点评:这篇文章是关于等待和waitpid之间的区别与联系,避免僵尸进程的出现,每当我们创建子进程,主进程需要等待子进程返回,以便清理过程。为此,我们将SIGCHLD信号处理函数的服务器程序。
在客户端断开连接,在服务器端大量僵尸进程。这是因为SIGCHLD信号是在服务器子进程终止发送给父进程,父进程的默许和默认的信号。为了避免僵尸进程的出现,每当我们创建子进程,主要过程需要等待子进程返回,以便清理过程。为此,我们将SIGCHLD信号处理功能的服务器程序。

复制代码代码如下所示:
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义serv_port 1113
#定义listenq 32
该#定义1024
***连接处理功能
无效str_echo(int fd);
无效
sig_chld(int该)
{
pid_t PID;
int属性;
pid =等待(统计);获取子进程。
printf(%d终止孩子
返回;
}
int
主要(int argc、argv { } { char *)
国际listenfd,connfd;
pid_t childpid;
socklen_t clilen;
结构sockaddr_in servaddr;
结构sockaddr_in cliaddr;
/ /结构sockaddr_in servaddr;
/ /结构sockaddr_in cliaddr;
如果((listenfd =插座(af_inet,sock_stream,0))= = 1){
Fprintf(stderr,套接字错误:%s
出口(1);
}
服务器结构填充SOCKADDR / * * /
BZero(servaddr,sizeof(servaddr));
servaddr.sin_family = af_inet;
servaddr.sin_addr.s_addr = htonl(inaddr_any);
servaddr.sin_port = htons(serv_port);
(SIGCHLD信号,sig_chld); / / SIGCHLD信号处理
捆绑listenfd描述符 / * * /
如果(绑定(listenfd,(struct sockaddr *)(servaddr),sizeof(struct sockaddr))= = 1){
Fprintf(stderr,绑定错误:%s
出口(1);
}
监控listenfd / * * /描述符
如果(听(listenfd,5)= = 1){
Fprintf(stderr,听错误:%s
出口(1);
}
为(;){
clilen = sizeof(cliaddr);
服务器被阻塞,构建到客户端程序连接为止。
如果((connfd =接受(listenfd,(struct sockaddr *)(cliaddr),clilen))<0){
*当一个子进程终止的sig_chld信号处理函数执行,
当函数返回时,接受系统调用会返回一个eintr误差,
一些内核会自动重新启动中断的系统调用,为了方便移植,将考虑eintr治疗。
如果(我= = eintr)
继续;
Fprintf(stderr,接受错误:%s
出口(1);
}
在与客户机建立连接之后。
如果((childpid)=叉()= = 0){ / * * /子过程
关闭(listenfd); / * * /密切监测插座
str_echo(connfd); / *客户端请求的处理
出口(0);
}
关闭(connfd); / *父进程关闭连接插座,继续等待其他连接的到来。
}
}
无效str_echo(int sockfd){
ssize_t n;
中字符{该};
再一次:
而((n =读(sockfd,buf,该))>0)
写(sockfd,buf,N);
如果(n<0 errno = = eintr) / /闯入
去了;
否则如果(n<0){错误
Fprintf(stderr,读取错误:%s
出口(1);
}
}

修改后的代码,当客户端断开连接,服务器的父进程的子进程收到SIGCHLD信号,然后执行sig_chld功能和清理的子过程,所以不会有僵尸的过程。在这一点上,当客户端断开时,积极,服务器端将输出以下信息:
孩子12306终止
等待和waitpid
在sig_chld功能在上述程序中,我们使用等待()明确终止子进程。也有类似的功能,wait_pid。让我们看一看这两个函数原型:
pid_t等待(int *状态);
pid_t waitpid(pid_t PID,int *状态,INT选项);
正式说明:所有这些系统调用都用于等待调用过程中的子类的状态更改,并获取状态更改的孩子的信息。一个国家的变化是:孩子在启发孩子停止;信号;或孩子恢复信号。对于被终止的孩子,执行等待可以让系统释放与孩子相关的资源,如果没有等待,那么执行终止的孩子仍然处于僵尸状态(请参阅下面的注释)。
等待和waitpid的区别与联系:
等待()系统调用暂停调用过程的执行直到一个
Waitpid(1,状态0);
的waitpid(系统)叫暂停调用进程执行直到孩子通过PID参数指定的状态已改变。默认情况下,waitpid(等),只为终止的孩子,但这种行为是可通过选择参数,如下所述。
就是等待()系统调用将挂断呼叫过程直到其任何子进程终止,呼叫等待的效果(状态)是调用waitpid相同(1,状态0)。
Waitpid()将挂起调用进程的PID参数的变化,直到指定的进程状态,默认情况下,waitpid()只等待子进程的终止状态。如果你需要,你可以处理非通过设置选项的值为终止状态:
期权的价值为零或以上。
wnohang立即返回,如果没有孩子的存在。
wuntraced也返回如果孩子已经停止(但不追查,但(2))。
wcontinued(因为Linux 2.6.10)如果一停孩子也已返回
等待一个非终止状态。
现在举个例子来看看之间的差异和waitpid等()()。
通过修改客户端程序,在客户端程序中设置5个套接字来立即连接到服务器,如下图所示(附加代码):

复制代码代码如下所示:
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义serv_port 1113
该#定义1024
无效str_cli(文件,int sockfd);
int
主要(int argc、argv char *)
{
int i,sockfd { 5 };
结构sockaddr_in servaddr;
如果(argc!= 2){
Fprintf(stderr,的用法:tcpcli ;
出口(0);
}
对于(i = 0;i < 5;+ i)建立的{服务器>和服务器五连接到服务器进程以创建5个孩子
如果((sockfd {我} =插座(af_inet,sock_stream,0))= = 1){
Fprintf(stderr,套接字错误:%s
出口(1);
}

客户机服务器数据填充
BZero(servaddr,sizeof(servaddr));
servaddr sin_family = af_inet;
servaddr sin_port = htons(serv_port);
如果(inet_pton(af_inet,argv { 1 },servaddr。sin_addr)<= 0){
Fprintf(stderr,inet_pton错误:%s
出口(1);
}
*客户端启动连接请求。
如果(连接(sockfd {我},(struct sockaddr *)(servaddr),sizeof(struct sockaddr))= = 1){
Fprintf(stderr,连接错误:%s
出口(1);
}
}
str_cli(stdin,sockfd { 0 }); / *只有第一个套接字与服务器通信。
出口(0);
}
无效
str_cli(文件,int sockfd)
{
int nbytes = 0;
焦sendline {该},recvline {该};
而(fgets(sendline,该,FP)!= NULL)从标准输入行读取
写(sockfd,sendline,strlen(sendline)); / /线路发送到服务器
如果((nbytes =读(sockfd,recvline,该))= = 0){ / /读取从服务器发送sockfd数据
Fprintf(stderr,str_cli:服务器提前终止;
出口(1);
}
recvline { nbytes } = 0;
作用是:将内容(recvline,stdout);
}
}

当客户端终止,所以打开描述符由内核自动关闭,所以在同一时间的5种基本连接,相当于5片也会发送到服务器,这将导致在同一时间终止5服务器进程,导致5 SIGCHLD信号几乎同时传递到服务器的父过程,如下图所示:
也就是说,几乎在同一时间,5个SIGCHLD信号给父进程,这将导致僵尸进程的存在。因为UNIX一般不排队的信号,这导致5 SIGCHLD提交,只执行一sig_chld功能,而剩下的四个子过程成为僵尸进程。在这种情况下,做正确的事是调用waitpid(),不等待()。
因此,我们在最后一个服务器端代码中对信号处理函数做了一些改变,并将其更改为以下内容:

复制代码代码如下所示:
无效
sig_chld(int该)
{
pid_t PID;
int属性;
而((PID = waitpid(- 1,统计,WNOHANG))>0)
printf(%d终止孩子
返回;
}

在这一点上,我们已经解决了网络编程中可能遇到的三种情况:
1。这必须捕获SIGCHLD信号当孩子出生时,代码段:(SIGCHLD信号,sig_chld);
2。当信号被捕获,被中断的系统调用必须被处理。代码段:如果(我= = eintr)继续;
的3.sigchld信号处理函数必须写正确防止僵尸进程。代码段:当(((PID = waitpid(- 1,统计,WNOHANG))>0)

相关文章

魔鬼之城是如何走出沼泽地和国王沼

魔鬼之城是如何走出沼泽地和国王沼

沼泽地,沼泽,之城,国王,魔鬼,问题: 最近,玩魔鬼城:影子王游戏,打开沼泽的第二个关卡,怎么不能出去杀了,什么技能都通过了 答案uff1a 恶魔城:暗影领主沼泽;游戏技巧:你需要行走在黑色沼泽的光,它不会被太阳;气泡消失时快速通过;最后,抓到一个QTE,仍大于…

RMANRMAN配置和常用命令操作

RMANRMAN配置和常用命令操作

配置,常用命令,命令操作,操作,电脑软件,一、RMAN相关配置 1。在进入RMAN RMAN目标 /:cmd 2,看看它在归档模式:SQL >归档日志列表;(RMAN需要运行在归档模式) 三.打开归档模式: 复制代码代码如下所示: 立即关闭; 启动挂载; 警告:更改数据库归档;(关闭数据…

的终极解决方案实例win7系统无法识

的终极解决方案实例win7系统无法识

无法识别,系统,解决方案,光驱,实例,点评:出现在windows7系统不能识别光驱,或在设备管理器显示驱动程序损坏或一个黄色的感叹号,可能是由于注册表中的错误的关键价值。本文带给我们的win7系统不能识别光驱的最终解决方案 Windows 7系统在CD-ROM…

基于MySQL事务、视图、存储过程、

基于MySQL事务、视图、存储过程、

存储过程,触发器,视图,事务,电脑软件,首先,MySQL事务 只有数据表在MySQL InnoDB类型可以支持事务处理。 启动事务有两种方法 (1)用开始、回滚、提交实现 复制代码代码如下所示: 开始事务 回滚事务回滚 提交交易验证 (2)用集合直接改变MySQL的…

对ngctw32.exe-使用ngctw32是什么

对ngctw32.exe-使用ngctw32是什么

电脑软件,exe,点评:ngctw32.exe是用于通过网络发送数据的Symantec Ghost服务程序 进程文件:ngctw32或ngctw32.exe 过程名称:赛门铁克Ghost组件 过程类别:安全风险的过程 英文描述: ngctw32.exe是与Symantec Ghost服务器相关的过程。它是服务器…

基于Linux的调试信息和gdb常用命令

基于Linux的调试信息和gdb常用命令

常用命令,调试,电脑软件,Linux,gdb,Strace和GDB是两种常用的调试工具在Linux环境下,这是在使用这两个工具的常用参数的过程的个人总结,检查后的当天。 Strace调试器 strace工具是用来跟踪系统调用和接收的信号执行该过程时,包括参数、返回值和…

青春是疯狂的奔跑,然后是华丽的坠落

青春是疯狂的奔跑,然后是华丽的坠落

疯狂,青春,电脑软件,华丽,我说的表,我的同桌是一个猪!她喊道,你是一个同桌的猪! 不管你的缺点是什么,你都可以说是遗传学;论据是美妙的! 灰色的日子,广阔的田野,学校的操场,充满了狼。 记住写作文后几个小时,云就会变成棉花糖,然后变成一坨屎。 青…

win7光盘不能由一个系统,是不承认的

win7光盘不能由一个系统,是不承认的

光盘,系统,不承认,制度,电脑软件,点评:升级到Windows7后,一个奇怪的问题是,DVD光盘是无法被系统识别。它只是设备管理器中的一个。解决这个问题有两种方法。 我不知道你有没有遇到一个很奇怪的问题升级到Windows7后:就是DVD光驱不被系统识别,但…

方法链也可以在PHP中使用。

方法链也可以在PHP中使用。

方法,电脑软件,PHP,简单的暗示: 复制代码代码如下所示: 类测试{ 私人_name美元=; 公共职能setName($name) { 美元-> _name = $名称; 返回$此; } 公共职能getName() { echo $这-> _name。; 返回$此; } } $ =新测试(); 链接方法 为链接-> setName('name1)->…

Win8全屏截图方法Win8捕获的默认位

Win8全屏截图方法Win8捕获的默认位

全屏截图,方法,位置,默认,技术,在过去,当我们想屏幕电脑屏幕,我们通常按打印screen和键盘上的键将屏幕关闭,然后打开图片处理软件,如PS图象处理软件,那么创造新的文件,粘贴截图,操作有点麻烦。现在,在Win8系统,有一个快速的方法截图。 在Win8电脑,按…

SkyDrive不支持HTTP下载迅雷下载(解

SkyDrive不支持HTTP下载迅雷下载(解

下载,迅雷,解决方案,不支持,电脑软件,问题: 经常使用百度的SkyDrive,下载的朋友共享软件或数据文件,但幸运的是,错误也可以是沉重的,如果大文件或软件,一旦出错,重新下载,花了很长时间,有什么可以让SkyDrive支持HTTP 答案uff1a 目前,大多数的SkyDri…

解决win8metro应用被暂停,无法重新

解决win8metro应用被暂停,无法重新

重新安装,暂停,电脑软件,win8metro,点评:很多朋友肯定遇到挂机Win8地铁中的应用情况,并不能安装后再挂。再次点击仍将挂断。这里有个好办法。你可以参考它。 故障现象: Win8系统Metro应用程序经常挂起来,不能挂装一遍后,再次点击或将挂,如下所示…