Linux----SignalReapChild

#define _GUN_SOURCE
#include <string.h>
#include <signal.h>
#include <time.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>
#include <errno.h>
//volatile是禁止CPU缓存,sig_atomic_t是一个原子操作的结构体
//所以这里定义的静态全局变量gotSigquit是一个不会被CPU缓存的进行原子操作的全局变量
static volatile sig_atomic_t Numchildren;

#define errExit(msg)	do{ preeor(msg); errExit(EXIT_FAILURE);}while(0)
    
void reap(int signum)	/* Signal handler function----Reap,父进程对子进程创建之后所发送的SIGCHLD信号进行处理的函数reap()*/
{
    pid_t child;
    while((child = waitpid(-1, 0, WNOHANG)) > 0)	//-1的二进制补码0xFFFFFFFF,类比于CN中的广播地址
    {
        Numchildren--;
        printf("Reaping the child %d\n", child);
    }
}
int main(int argc, char *argv[])
{
    int pid;
    int numchildren = atoi(argv[1]);
    Numchildren = numchildren;
    int *children = malloc(numchildren * sizeof(int));
    
    //信号处理函数sigaction()
    struct sigaction act;
    act.sa_handler = reap;
    act.sa_flags = 0;
    sigemptyset(&act.sa_mask);
    sigaction(SIGCHLD, &act, NULL);	/* 对SIGCHLD信号进行处理 */
    
    for(int i = 0; i < numchildren; i++)
    {
        if((children[i] = fork()) == 0)	/* 父进程fork子进程 */
        {
            free(children);	/* 子进程会获得父进程的内存映像,因此选择一个合适的时间去释放这个不必要的内存占用是并发编程的细节之一 */
            printf("This is the child %d\n", getpid());
            sleep(i+5);	/* 每fork一个子进程后sleep一会儿,然后才会给父进程发送SIGCHLD信号,然后再退出这层循环exit(0) */
            exit(0);
        }
    // 让子进程的处理函数reap()回收时,不再等待sleep(i+5),而是直接被杀死,然后由处理函数reap()回收。但是这个发送SIGKILL信号的函数kill()不是一直发送的,这里设置了每三秒发送一个SIGKILL信号
    // for(int j = 0; j < numchildren; j++)
    // {
    //     sleep(3);
    //     kill(children[j], SIGKILL);
    // }
    }
    while(Numchildren)
    	pause();

    free(children);
    exit(0);
}
gurenyu@192:~/Documents/CodeLinux> ./Reapchild 4
This is the child 33325
This is the child 33326
This is the child 33327
This is the child 33328
Reaping the child 33325
Reaping the child 33326
Reaping the child 33327
Reaping the child 33328
gurenyu@192:~/Documents/CodeLinux> 

若将kill()函数加入之后,回收函数reap()的打印不会再出现等待的过程,而是直接回收。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值