Skip to content

Instantly share code, notes, and snippets.

@SarKerson
Created December 21, 2018 06:32
Show Gist options
  • Save SarKerson/0eadf19065c2aacb63c3a811d3031f19 to your computer and use it in GitHub Desktop.
Save SarKerson/0eadf19065c2aacb63c3a811d3031f19 to your computer and use it in GitHub Desktop.
version4_process_in_main.md

显式等待信号

该程序在主函数中等待SIGCHLD,直到信号处理函数对某个全局变量进行修改后,主函数捕捉该变化,再继续运行。

sigsuspend(mask)

该函数使用mask代替当前的信号屏蔽字,将程序挂起,直到捕获到信号,其行为要么运行一个handler,要么终止程序。

result(先运行handler再运行主函数后边的处理)

Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
Hello from child
# Got signal from child!
# Done fork()
total count: 10

code

#include <sys/wait.h>
#include <sys/signal.h>
#include <errno.h>
#include <stdbool.h>
#include "apue.h"

volatile int counter = 0;
volatile bool flag = 0;

void handler(int sig)
{
    sigset_t mask_all, mask_pre;
    sigfillset(&mask_all);
    sigprocmask(SIG_BLOCK, &mask_all, &mask_pre);
    char msg[] = "# Got signal from child!\n";
    write(STDOUT_FILENO, msg, strlen(msg));
    ++counter;
    flag = 1;
    sigprocmask(SIG_UNBLOCK, &mask_pre, NULL);   
}

int main()
{
    if (signal(SIGCHLD, handler) == SIG_ERR) {
        printf("signal error\n");
    }
    sigset_t mask_one, mask_pre;
    sigemptyset(&mask_one);
    sigaddset(&mask_one, SIGCHLD);
    signal(SIGCHLD, handler);
    for (int i = 0; i < 10; ++i) {
        sigprocmask(SIG_BLOCK, &mask_one, &mask_pre);
        if (fork() == 0) {
            // child
            char msg[] = "Hello from child\n";
            write(STDOUT_FILENO, msg, strlen(msg));
            exit(0);
        }
        while (!flag) {
            sigsuspend(&mask_pre);
        }
        flag = 0;
        char msg[] = "# Done fork()\n";
        write(STDOUT_FILENO, msg, strlen(msg));
        sigprocmask(SIG_SETMASK, &mask_pre, NULL);
    }
    printf("total count: %d\n", counter);
    exit(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment