SIGCHLD信号

发布于:2024-04-07 ⋅ 阅读:(144) ⋅ 点赞:(0)

1.子进程结束,父进程会收到内核发送的SIGCHLD信号;(注意:内核发送)

前面的代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

int main()
{
    int n=0;
    char *s=NULL;
    pid_t pid=fork();
   if(pid==-1)
   {
       printf("fork err\n");
       exit(1);
   } 
    if(pid==0)
   {
     n=3;
     s="child";
   } 
    else
  {
     n=7;
     s="parent";
  } 
  for(int i=0;i<n;i++)
  {
     printf("s=%s\n",s);
     sleep(1);
  } 
  exit(0);
}

父进程没有获取退出码,是会产生僵死进程的;

在这里其实子进程结束了,已经给父进程发送了一个信号.只不过父进程忽略了;

那么在这里,我们修改一下代码,让父进程收到子进程的代码,打印一下收到的信号代号,不要忽略掉;

signal(SIGCHLD,fun);     //父进程那里添加

//回调函数如下:
void fun(int sig)
{
   printf("sig=%d\n",sig);
   printf("child over\n");
}

由执行结果可以看出,子进程结束,确实是会给父进程发送17号信号SIGCHLD;只不过遇到默认情况,父进程不会理会而已;所以,这个17号信号的默认方式就是忽略;

再次强调一下,这个不是子进程发送的信号,是内核发送的信号;

2.处理僵死进程

回顾前面知识点:
1)演示僵死进程
2)处理僵死进程的方法
(1).父进程先结束(孤儿进程会被收养)
(2).父进程调用wait()方法获取子进程的退出码 父进程获取子进程的退出码之后,操作系统就将这个子进程的PCB删除了,就不会产生僵死进程了. 两个方法的本质是一样的,但是方法二会阻塞,就是父进程在子进程结束,才会获取退出码.
结合信号,如何处理,让它不再阻塞呢?
父进程调用wait是配合信号使用的.代码如下:

void fun(int sig)
{
   printf("sig=%d\n",sig);
   int val=0;
   int id=wait(&val);
} 
//注意,wait的头文件需要加一下:
#include <wait.h>

而且我们也可以简单写,就是不获取退出码,我们只要不变成僵死进程就可以;

wait(NULL);


网站公告

今日签到

点亮在社区的每一天
去签到