Ubuntu C Как остановить дочерний процесс с помощью SIGTSTP, а затем возобновить его с помощью SIGCONT? - PullRequest
0 голосов
/ 14 марта 2020
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>


int pid = 0;

// some very time-consuming function
void childLabor() {
    for (long long i=1;i<=10000000000;i++) {
        //printf("i'm printing\n");
        fflush(stdout);
    }
}

// stop the process who calls this
void stopYourself() {
    // TODO
}

void childReceiveStop() {
    signal(SIGTSTP, childReceiveStop);
    printf("I have important things to do first before stopping\n");
    fflush(stdout);
    // do important things

    printf("I stop myself now\n");
    fflush(stdout);
    stopYourself();
}

void childReceiveContinue() {
    signal(SIGCONT, childReceiveContinue);
}

int main()
{
    pid = fork();
    if (pid==0) {
        signal(SIGTSTP, childReceiveStop);
        signal(SIGCONT, childReceiveContinue);
        stopYourself();     // wait until parent sends SIGCONT
        childLabor();
    }
    else {
        // start/stop child every 2 second
        kill(pid,SIGCONT);
        for (int i=1; i<=100; i++) {
            printf("sending signal stop\n");
            fflush(stdout);
            kill(pid, SIGTSTP);
            sleep(3);

            printf("sending signal start\n");
            kill(pid, SIGCONT);
            sleep(1);
        }
    }

    return 0;
}

По сути, в этом примере я хочу, чтобы дочерний процесс печатал в течение 3 секунд, затем останавливал его, затем позволял печатать снова, ... Когда дочерний объект получает SIGTSTP, он должен остановиться. И когда он получает SIGCONT, он должен продолжать.

Однако, с обработчиком или без него, когда дочерний процесс получает сигнал SIGTSTP, он вообще не останавливается.

Как я могу решить эту проблему? Спасибо.

1 Ответ

0 голосов
/ 15 марта 2020

SIGTSTP для отправки сигнала остановки с терминала на процесс. В вашем случае вы хотите отправить сигнал остановки от родительского процесса. Так что вам нужно SIGSTOP вместо SIGTSTP. Поэтому замените SIGTSTP на SIGSTOP.

Также SIGSTOP не может быть пойман. Так что вам не нужно иметь обработчики для SIGSTOP.

...