使用c语言调度报警

使用c语言调度报警,c,alarm,C,Alarm,我们的任务是开发一个创建子进程的应用程序。然后,父进程等待3秒钟(不允许在父进程中使用sleep),然后发送SIGUSR2信号,然后发送SIGUSR1信号。在此之后,父节点定期(3秒)向子节点发送SIGUSR1信号,直到终止。在子级终止时,它打印父级完成并退出。我们应该使用alarm()和pause()实现这种行为 子进程应将信号SIGUSR2阻塞13秒。在接收到SIGUSR1后,应打印接收到的SIGUSR1。接收到SIGUSR2后,它将打印Child done并退出。我的实施方法如下: 请注意

我们的任务是开发一个创建子进程的应用程序。然后,父进程等待3秒钟(不允许在父进程中使用
sleep
),然后发送
SIGUSR2
信号,然后发送
SIGUSR1
信号。在此之后,父节点定期(3秒)向子节点发送
SIGUSR1
信号,直到终止。在子级终止时,它打印
父级完成
并退出。我们应该使用
alarm()
pause()
实现这种行为

子进程应将信号
SIGUSR2
阻塞13秒。在接收到
SIGUSR1
后,应打印
接收到的SIGUSR1
。接收到
SIGUSR2
后,它将打印
Child done
并退出。我的实施方法如下:

请注意
SIGUSR2
信号只发送一次,直到现在我还没有实现这一点,它每次都与
SIGUSR1
信号一起发送

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <stdarg.h>

static pid_t chld;

void init_signal(struct sigaction* action, void (*handler)(int));
void init_sigset(sigset_t* set, int signum);
void bind_signal(struct sigaction* action, int n, ...);
void par_signal(int signum);
void chld_signal(int signum);

int main(){
    chld = fork();
    struct sigaction action;

    if (chld == -1){
        fprintf(stderr, "Failed to create child process.\n");
        return EXIT_FAILURE;
    } else if (chld == 0){
        init_signal(&action, &chld_signal);
        bind_signal(&action, 3, SIGUSR1, SIGUSR2, SIGALRM);        

        sigset_t sig;
        init_sigset(&sig, SIGUSR2);

        sigprocmask(SIG_BLOCK, &sig, NULL);
        alarm(13);
        pause();
    }
    init_signal(&action, &par_signal);
    bind_signal(&action, 2, SIGALRM, SIGCHLD);

    alarm(3);
    pause();
}

void init_signal(struct sigaction* action, void (*handler)(int)){
    action->sa_flags = 0;
    action->sa_handler = handler;

    sigemptyset(&action->sa_mask);
}

void init_sigset(sigset_t* set, int signum){
    sigemptyset(set);
    sigaddset(set, signum);
}

void bind_signal(struct sigaction* action, int n, ...){
    va_list args;
    va_start(args, n);

    for (int i = 0; i < n; i++){
        int signum = va_arg(args, int);
        sigaction(signum, action, NULL);
    }
    va_end(args);
}

void par_signal(int signum){
    if (signum == SIGALRM){
        kill(chld, SIGUSR2);
        kill(chld, SIGUSR1);
        alarm(3);
        pause();
    } else if (signum == SIGCHLD){
        printf("Parent done\n");
        exit(EXIT_SUCCESS);
    }
}

void chld_signal(int signum){
    if (signum == SIGALRM){
        sigset_t sig;
        init_sigset(&sig, SIGUSR2);

        sigprocmask(SIG_UNBLOCK, &sig, NULL);
        pause();
    } else if (signum == SIGUSR1){
        printf("Received SIGUSR1\n");
        pause();
    } else if (signum == SIGUSR2){
        printf("Child done\n");
        exit(EXIT_SUCCESS);
    }
}
#包括
#包括
#包括
#包括
#包括
静态pid_t chld;
void init_信号(struct sigaction*action,void(*handler)(int));
void init_sigset(sigset_t*set,int signum);
无效绑定信号(结构sigaction*action,int n,…);
无效par_信号(内部信号);
无效chld_信号(内部信号);
int main(){
chld=fork();
结构动作;
如果(chld==-1){
fprintf(stderr,“未能创建子进程。\n”);
返回退出失败;
}else如果(chld==0){
初始信号(动作和时钟信号);
绑定_信号(和动作,3,SIGUSR1,SIGUSR2,SIGALRM);
sigset_t sig;
初始化sigset(&sig,SIGUSR2);
sigprocmask(SIG_块和SIG,空);
警报(13);
暂停();
}
初始信号(动作和par信号);
绑定_信号(和动作,2,信号,信号);
警报(3);
暂停();
}
void init_信号(结构sigaction*action,void(*handler)(int)){
操作->SAU标志=0;
action->sa_handler=handler;
sigemptyset(&action->sa_mask);
}
void init_sigset(sigset_t*set,int signum){
sigp(套);
sigaddset(set,signum);
}
无效绑定信号(结构sigaction*action,int n,…){
va_列表参数;
va_启动(args,n);
对于(int i=0;i
它的工作原理与以下事实不同:子进程只接收父进程的第一个信号。我想这与我分别使用
暂停
报警
有关。你知道我做错了什么吗


可以找到指向练习任务单的链接(任务3)。

在信号处理程序中调用
暂停
是有问题的,因为在这种情况下,刚刚触发信号处理程序的信号会被阻止,直到您从信号处理程序返回。这意味着该过程将不再对该信号作出反应。信号处理器只能由其他信号触发

请参见下面的系统调用跟踪和说明。为了清楚起见,我用
@parent@
替换了家长的PID,用
#child##
替换了孩子的PID

$strace-f-r-e trace=信号,进程。/proc
0.000000 execve(“./proc”,[”/proc“],0x7ffc146ba360/*74 vars*/)=0
0.001428 arch_prctl(0x3001/*arch_???*/,0x7ffd3c958fc0)=-1 EINVAL(无效参数)
0.002302拱度prctl(拱度设置FS,0x7f264e40a540)=0
#克隆是fork()
0.001086克隆(strace:Process#CHILD#附件
child_stack=NULL,flags=CLONE_child_CLEARTID | CLONE_child_SETTID | SIGCHLD,child_tidptr=0x7f264e40a810)=#child##
#父级建立SIGALRM处理程序
[pid@PARENT@]0.000791 rt_sigaction(SIGALRM,{sa_handler=0x564709a5859c,sa_mask=[],sa_flags=sa_RESTORER,sa_RESTORER=0x7f264e25e470},
#子进程建立SIGUSR1处理程序
[pid#CHILD##0.000087 rt#U SIGATION(SIGUSR1,{sa#U handler=0x564709a58605,sa#U mask=[],sa#U flags=sa#U RESTORER,sa#U RESTORER=0x7f264e25e470},
[pid@PARENT@]0.000132空,8)=0
[pid#CHILD##]0.000056 NULL,8)=0
#子进程建立SIGUSR2处理程序
[pid#CHILD##0.000072 rt#U SIGATION(SIGUSR2,{sa#U handler=0x564709a58605,sa#U mask=[],sa#U flags=sa#U RESTORER,sa#U RESTORER=0x7f264e25e470},NULL,8)=0
#子进程建立SIGALRM处理程序
[pid#CHILD##0.000141 rt#U sigaction(SIGALRM,{sa#U handler=0x564709a58605,sa#U mask=[],sa#U flags=sa#U RESTORER,sa#U RESTORER=0x7f264e25e470},NULL,8)=0
#父级建立SIGCHLD处理程序
[pid@PARENT@]0.000389 rt_sigaction(SIGCHLD,{sa_handler=0x564709a5859c,sa_mask=[],sa_flags=sa_RESTORER,sa_RESTORER=0x7f264e25e470},
#子块SIGUSR2
[pid#CHILD##]0.000132 rt#U sigprocmask(SIG#U块[USR2],NULL,8)=0
#孩子等待信号
[pid#CHILD##]0.000204暂停(
[pid@PARENT@]0.000837空,8)=0
#家长等待信号
[pid@PARENT@]0.000133 pause()=?ERESTARTNOHAND(如果没有处理程序,则重新启动)
#父级收到SIGALRM
[pid@PARENT@]3.000317--SIGALRM{si_signo=SIGALRM,si_code=si_KERNEL}---
#父级将SIGUSR2和SIGUSR1发送给子级
[pid@PARENT@]0.000106 kill(#CHILD##,SIGUSR2)=0
[pid@PARENT@]0.000116 kill(#CHILD##,SIGUSR1)=0
[pid#CHILD##]0.000144)=?埃雷斯塔特诺汉德
static volatile sig_atomic_t childSigUsr1 = 0;
static volatile sig_atomic_t childSigUsr2 = 0;
static volatile sig_atomic_t childSigAlrm = 0;

void chld_signal(int signum) {
    if (signum == SIGALRM) {
        childSigAlrm = 1;
    } else if (signum == SIGUSR1) {
        childSigUsr1 = 1;
    } else if (signum == SIGUSR2) {
        childSigUsr2 = 1;
    }
}

int main() {
    chld = fork();
    struct sigaction action;

    if (chld == -1) {
        fprintf(stderr, "Failed to create child process.\n");
        return EXIT_FAILURE;
    } else if (chld == 0) {
        init_signal(&action, &chld_signal);
        bind_signal(&action, 3, SIGUSR1, SIGUSR2, SIGALRM);        

        sigset_t sig;
        init_sigset(&sig, SIGUSR2);

        sigprocmask(SIG_BLOCK, &sig, NULL);
        alarm(13);
        while(1) {
            pause();
            if(childSigUsr1) {
                childSigUsr1 = 0;
                printf("Received SIGUSR1\n");
            }
            if(childSigUsr2) {
                childSigUsr2 = 0;
                printf("Child done\n");
                exit(EXIT_SUCCESS);
            }
            if(childSigAlrm) {
                sigset_t sig;
                init_sigset(&sig, SIGUSR2);

                sigprocmask(SIG_UNBLOCK, &sig, NULL);
            }
        }
    }
    init_signal(&action, &par_signal);
    bind_signal(&action, 2, SIGALRM, SIGCHLD);

    while(1) {
        alarm(3);
        pause();
        /* handle and reset signal flags similar to child */
    }
}