簡體   English   中英

嘗試在循環中隨機將信號從父進程發送到子進程

[英]Trying to randomly send signal from parent to child process in a loop

我試圖讓它在一個循環中執行,父進程在 SIGUSR1 和 SIGUSR2 之間隨機選擇並將其發送到子進程以接收和寫入文件

我的問題是信號只會在第一個循環中發送,然后停止

int main(int argc, char* argv[], char *envp[]){
    time_t start, finish; //for example purposes, to save the time
    
    struct sigaction sact; //signal action structure
    sact.sa_handler = &handler;
    sact.sa_handler = &handler2;
    sigset_t new_set, old_set; //signal mask data-types
    FILE *file = fopen("received_signal.txt", "w");
    fprintf(file,"%s\t %s\t %s\n", "Signal Type", 
    "Signal Time", "thread ID");
    fclose(file);
    
    int pid;
    int cpid;
    pid = fork();

    if(pid == 0){//recieves
        //sigaction(SIGUSR1, &sact, NULL);
        while(1){
       
            signal(SIGUSR1, handler);
            signal(SIGUSR2, handler2);
 
            sleep(1);
    
        
        }
    } else{ //generates 
        while(1){
   
            sleep(1); // give child time to spawn
            printf("hello\n");
            parent_func(0);

            
            //wait(NULL);
            usleep(((rand() % 5) + 1) * 10000);
        }
    }
    
    return 0;
}


void parent_func(int child_pid){
    srand(time(NULL));
    int rnd = rand();
    int result = (rnd & 1) ? 2 : 1;

    struct timeval t;
    gettimeofday(&t, NULL);
    unsigned long time = 1000000 * t.tv_sec + t.tv_usec;
    printf("result: %d\n", result);
    printf("time: %ld\n", time);

    if(result == 1){
        //sigaction(SIGUSR1, &sact, NULL);
        kill(child_pid, SIGUSR1);
        log(SIGUSR1);
    } else{
        //sigaction(SIGUSR2, &sact, NULL);
        kill(child_pid, SIGUSR2);
        log(SIGUSR2);
    }
}

void handler(int sig){
    if (sig == SIGUSR1){
        puts("child received SIGUSR1");
    }

    
}
void handler2(int sig){
    if (sig == SIGUSR2){
        puts("child received SIGUSR2");
    }
    
}

嘗試將孩子扔進 while 循環以使其重復但沒有這樣的運氣

man signal(2) 告訴您,一旦信號被傳遞,處理程序就會重置為 SIG_DFL:

如果配置設置為 function,則首先將配置重置為 SIG_DFL,或者信號被阻止(請參閱下面的可移植性),然后使用參數 signum 調用處理程序。 如果處理程序的調用導致信號被阻塞,則信號在從處理程序返回時解除阻塞。

我建議你使用 sigaction 而不是信號:

#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 199309L
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>

void handler(int sig) {
    char s[] = "child received signal SIGUSR?\n";
    char *s2 = strchr(s, '?');
    *s2 = sig == SIGUSR1 ? '1' : '2';
    write(STDOUT_FILENO, s, strlen(s));
}

int main(int argc, char* argv[], char *envp[]){
    pid_t child_pid = fork();
    if(!child_pid) {
        struct sigaction sa = {
            .sa_handler = &handler
        };
        sigaction(SIGUSR1, &sa, NULL);
        sigaction(SIGUSR2, &sa, NULL);
        for(;;) {
            sleep(1);
        }
        return 0;
    }
    for(;;) {
        sleep(1);
        int s = (int []){SIGUSR1, SIGUSR2}[rand() % 2];
        printf("parent sending signal %d to %d\n", s, child_pid);
        kill(child_pid, s);
    }
}

和樣本 output:

parent sending signal 12 to 521586
child received signal SIGUSR2
parent sending signal 10 to 521586
child received signal SIGUSR1
parent sending signal 12 to 521586
child received signal SIGUSR2
parent sending signal 12 to 521586
child received signal SIGUSR2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM