Pitfalls in Multiprocessing

Signal handling examples (in-class discussion)

For the following examples, discuss: Is this safe?

Example 1: Exit on ctrl+c

Cplayground

void handler(int sig) {
    printf("Bye.\n");
    exit(0);
}

int main() {
    signal(SIGINT, handler);
    while (true) {
        sleep(1);
    }
    return 0;
}

Example 2: Troll program, print a message on ctrl+c

Cplayground

void handler(int sig) {
    printf("Hehe, not exiting!\n");
}

int main() {
    signal(SIGINT, handler);
    while (true) {
        printf("Looping...\n");
        sleep(1);
    }
    return 0;
}

Example 3: Count number of SIGCHLDs received

Cplayground

static volatile int sigchld_count = 0;

void handler(int sig) {
    sigchld_count += 1;
}

int main() {
    signal(SIGCHLD, handler);
    const int num_processes = 10;
    for (int i = 0; i < num_processes; i++) {
        if (fork() == 0) {
            sleep(1);
            exit(0);
        }
    }
    while (waitpid(-1, NULL, 0) != -1) {}
    printf("All %d processes exited, got %d SIGCHLDs.\n",
        num_processes, sigchld_count);
    return 0;
}

Example 4: Count number of running processes

Cplayground

static volatile int running_processes = 0;

void handler(int sig) {
    while (waitpid(-1, NULL, WNOHANG) > 0) {
        running_processes -= 1;
    }
}

int main() {
    signal(SIGCHLD, handler);
    const int num_processes = 10;
    for (int i = 0; i < num_processes; i++) {
        if (fork() == 0) {
            sleep(1);
            exit(0);
        }
        running_processes += 1;
        printf("%d running processes\n", running_processes);
    }
    while(running_processes > 0) {
        pause();
    }
    printf("All processes exited! %d running processes\n", running_processes);
    return 0;
}