signal(SIGCHLD, SIG_IGN);的使用及验证

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include<stdlib.h>
#include<signal.h>
int main(int argc , char **argv)
{signal(SIGCHLD, SIG_IGN);
 int id;
 id=fork();
 if(id<0)
  {
  printf("fork error\n");
  }
 else if(id==0)
  {
   printf("I‘m in child process%d parent process%d\n",getpid(),getppid());
   exit(0);
   }
 else if(id>0)
   {
   printf("I‘m in parent process%d\n",getpid());
   sleep(60);
   }
   //signal(SIGCHLD, SIG_IGN);
  return 0;
}
[[email protected] Desktop]# gcc 僵尸进程.c
[[email protected] Desktop]# ./a.out
I‘m in parent process8072
I‘m in child process8073 parent process8072  //第二行
[[email protected] Desktop]#
在第二行输出后会阻塞大概1分钟,我们执行以下命令
[[email protected] Desktop]# ps aux | grep  ‘Z‘
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      8076  0.0  0.0   4340   740 pts/1    S+   22:47   0:00 grep Z
可以发现没有僵尸进程啊,感觉很奇怪吧!
这是因为init进程调用wait把子进程的进程表项等资源清理了!
为啥子进程没有成为僵尸进程而成为了init的子进程呢?
很奇怪吧!因为signal(SIGCHLD, SIG_IGN);这一行代码,所以子进程成为了init的子进程!
一定要注意signal(SIGCHLD, SIG_IGN);的位置,因为程序执行时,是从上面往下执行的,因为我们执行那些
命令时,这行代码还未执行,然而这时子进程已经成为了僵尸进程了!见下面
如果这行代码的位置在最后面,那么结果将是不一样的,下面就是执行结果:
[[email protected] Desktop]# ps aux | grep -w ‘Z‘
root      8734  0.0  0.0      0     0 pts/0    Z+   23:32   0:00 [a.out] <defunct>
root      8737  0.0  0.0   4336   792 pts/1    S+   23:32   0:00 grep -w Z
[[email protected] Desktop]# 可以看出产生了僵尸进程!

我们可以用ps --ppid 1来查看父进程号为1的进程!(那个进程号都可以)
也可以用  ps --pid 1 来查看进程号为1的进程
[[email protected] Desktop]# ps --pid 1
  PID TTY          TIME CMD
    1 ?        00:00:04 init
但是我们一定要记住使用这些命令时,一定要记住在程序运行时,才能得到结果的!程序一旦结束是看不到的!
下面是一个例子,在一个窗口中
[[email protected] Desktop]# ./a.out
I‘m in parent process8853
I‘m in child process8854 parent process8853//会停顿大概一分钟,为了能看清楚
[[email protected] Desktop]#
下面的要在另一个窗口看
[[email protected] Desktop]# ps --pid 8854
  PID TTY          TIME CMD
 8854 pts/0    00:00:00 a.out
[[email protected] Desktop]# ps --ppid 8853
  PID TTY          TIME CMD
 8854 pts/0    00:00:00 a.out
[[email protected] Desktop]# ps --ppid 8853
  PID TTY          TIME CMD         //注意这儿没有输出任何结果,是因为程序执行结束了
[[email protected] Desktop]#
一定要记住在程序正在运行时看,包括查看僵尸进程,因为一旦程序结束了,那么僵尸进程估计就看不到了!切记。。。
时间: 2024-08-29 07:21:16

signal(SIGCHLD, SIG_IGN);的使用及验证的相关文章

signal(SIGCHLD, SIG_IGN)和signal(SIGPIPE, SIG_IGN);

signal(SIGCHLD, SIG_IGN)和signal(SIGPIPE, SIG_IGN); signal(SIGCHLD, SIG_IGN); 因为并发服务器常常fork很多子进程,子进程终结之后需要服务器进程去wait清理资源.如果将此信号的处理方式设为忽略,可让内核把僵尸子进程转交给init进程去处理,省去了大量僵尸进程占用系统资源.(Linux Only) 对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求.如果父进程不等待子进程结束,子进程将成为僵尸进程(zomb

signal(SIGPIPE, SIG_IGN)作用

signal(SIGPIPE, SIG_IGN) 当服务器close一个连接时,若client端接着发数据. 根据TCP 协议的规定,会收到一个RST响应,client再往这个服务器发送数据时,系统会发出一个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了. 根据信号的默认处理规则SIGPIPE信号的默认执行动作是terminate(终止.退出),所以client会退出. 若不想客户端退出可以把SIGPIPE设为SIG_IGN 如:    signal(SIGPIPE,SIG_I

signal(SIGPIPE, SIG_IGN)

转自http://blog.163.com/[email protected]/blog/static/170596595201221942952676/ 当服务器close一个连接时,若client端接着发数据.根据TCP 协议的规定,会收到一个RST响应,client再往这个服务器发送数据时,系统会发出一个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了. 根据信号的默认处理规则SIGPIPE信号的默认执行动作是terminate(终止.退出),所以client会退出.若不想

为什么程序中,常会用到signal(SIGCHLD,SIG_DFL)

为什么程序中,常会用到signal(SIGCHLD,SIG_DFL) 执行system函数时,SIGCHLD信号,最好被显示的: signal( SIGCHLD, SIG_DFL ) 一下,因为system函数中,使用到了fork(),waitpid.如果父进程忽略了SIGCHID信号,waitpid就没有不能得到子进程的SIGCHLD信号,那么,处理的返回值就会有问题.system的返回值也会有问题.通常的做法是: signal( SIGCHLD, SIG_DFL ); system( com

signal(SIGPIPE, SIG_IGN) (转)

signal(SIGPIPE, SIG_IGN) (转) signal(SIGPIPE, SIG_IGN) 当服务器close一个连接时,若client端接着发数据. 根据TCP 协议的规定,会收到一个RST响应,client再往这个服务器发送数据时,系统会发出一个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了. 根据信号的默认处理规则SIGPIPE信号的默认执行动作是terminate(终止.退出),所以client会退出. 若不想客户端退出可以把SIGPIPE设为SIG_I

SIGCHLD 信号处理

linux下进程终止时,内核会向父进程发送一个SIGCHLD信号,其有几个特点: 1.在一个信号处理函数运行期间,正被递交的信号是阻塞的. 2.如果一个信号在被阻塞期间产生了一次或多次,那么该信号被解阻塞之后通常只递交一次,也就是说linux信号默认是不排队的. 举个栗子: 进程的第一个子进程终止产生信号(1),(1)信号处理过程中第二个子进程终止产生信号(2),此时(1)处于正在处理状态,(2)处于等待处理状态,接着又有第三.四.五子进程终止产生信号(3)(4)(5):(1)信号处理函数执行完

init进程接管孤儿进程的验证

  #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include<stdlib.h> #include<signal.h> int main(int argc , char **argv) { int id; id=fork(); if(id<0) { printf("fork error\n"); } else if(id==0) { pr

linux编程下signal()函数

linux编程下signal()函数 当服务器close一个连接时,若client端接着发数据.根据TCP协议的规定,会收到一个RST响应,client再往这个服务器发送数据时,系统会发出一个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了.根据信号的默认处理规则SIGPIPE信号的默认执行动作是 terminate(终止.退出), 所以client会退出. 若不想客户端退出可以把 SIGPIPE设为SIG_IGN 如: signal(SIGPIPE,SIG_IGN); 这时SI

linux signal

当服务器close一个连接时,若client端接着发数据.根据TCP协议的规定,会收到一个RST响应,client再往这个服务器发送数据时,系统 会发出一个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了.根据信号的默认处理规则SIGPIPE信号的默认执行动作是 terminate(终止.退出), 所以client会退出. 若不想客户端退出可以把 SIGPIPE设为SIG_IGN 如:    signal(SIGPIPE,SIG_IGN); 这时SIGPIPE交给了系统处理. 服