如何使多个子进程暂停直到发送信号

时间:2018-12-04 05:18:30

标签: c systems-programming

我有一个程序,其中三个子进程都执行完全相同的操作,第四个子进程被告知发送信号,而主函数则等待直到三个子进程完成。我正在使用一个警报信号以及两个用户信号,以使子进程将输出发送到另一个终端。我正在使用暂停功能来等待信号,但是第二秒我启动了它完成的程序,根本没有等待。我可以正确使用暂停吗?

int alarmR =0;
int SNMPR =0;
int reconR=0;
int child_pid[4];
char strD[100];
FILE *fpt[4];


void Alarmhandler(int sig);
void Reconfigure(int sig);
void SNMPhandler(int sig);
int which(int wait_ret, int child_proc[], int p);
void IT1(void);
void IT2(void);
void IT3(void);
void command(void);


void command(void)
{
    signal(SIGALRM,Alarmhandler);
        signal(SIGUSR1,Reconfigure  );
        signal(SIGUSR2,SNMPhandler  );

        char text;
        int n;
        printf("please enter a command from the following list\n");
        printf("\tsn:Send a SNMP request\n\trn:Send a reconfiguration");
        printf("script\n\tkn: shutdown process\n");
        scanf("%c%d",&text,&n);
        if(text == 'k')
        {
            printf("Terminated IT service %d\n",n);
            n = n-1;
            kill(child_pid[n],1);
        }
        else if(text=='s')
        {
            n = n-1;
            kill(child_pid[n],SIGUSR2);
        }
        else if(text=='r')
        {
            n = n-1;
            kill(child_pid[n],SIGUSR1);
        }

}   

void Alarmhandler(int sig)
{

    alarmR =1;

}

void Reconfigure(int sig)
{
    reconR =1;
}

void SNMPhandler(int sig)
{
    SNMPR =1;
}


int which(int wait_ret, int child_proc[], int p)
{
    int i;
    for (i = 0; i < p; i++)
        if (child_proc[i] == wait_ret)
            return i;
    return -1;
}




int main(int argc, char *argv[])
{
    int ttyindex;
//  int Terminal[4];
    int term_cnt = 0;
    int wait_r,x;
    int process = 0;
    int child_proc[4];
    int es[3];


    if(argc != 5) {
        printf("Usage: ./lab7 1 2 3 4\n");
        exit(1);
    }
    for(term_cnt =0; term_cnt <4;term_cnt ++)
    {
        ttyindex = -1;
        ttyindex = atoi(argv[term_cnt+1]);
        if (ttyindex < 1) {
             printf("invalid terminal number %s\n", argv[term_cnt+1]);
                exit(1);
        }
        sprintf(strD, "/dev/pts/%d", ttyindex);
    child_proc[process] = fork();
        if (child_proc[process] != 0) 
    {
        // parent process
        process++;
        child_proc[process] = fork();
        if (child_proc[process] != 0) 
        {
            // parent process
            process++;
                child_proc[process] = fork();
                if (child_proc[process] != 0) 
            {
                // parent process
                    process++;
                child_proc[process] = fork();
                if(child_proc[process] !=0)
                {
                        wait_r = wait(NULL);
                             x =which(wait_r, child_proc, process);

                        printf("Waited for %d (child %d) to finish.\n", wait_r,x);
                    if(WIFEXITED(wait_r))
                    {
                        es[x] = WEXITSTATUS(wait_r);
                    }

                        wait_r = wait(NULL);
                             x =which(wait_r, child_proc, process);

                        printf("Waited for %d (child %d) to finish.\n", wait_r,x);
                    if(WIFEXITED(wait_r))
                    {
                         es[x] = WEXITSTATUS(wait_r);
                    }

                        wait_r = wait(NULL);
                             x =which(wait_r, child_proc, process);

                        printf("Waited for %d (child %d) to finish.\n", wait_r,x);

                    if(WIFEXITED(wait_r))
                    {
                         es[x] = WEXITSTATUS(wait_r);
                    }
                    for(x = 0; x <3;x++)
                    {
                        if(es[x] == 0)
                        {
                            printf("\nJob well done IT specialist %d",(x+1));
                            printf(" Prepare for new attacks!\n");
                        }
                        else if(es[x] == 1)
                        {
                            printf("\nIT service %d compromised",(x+1));
                            printf(" , we are going out of business!\n");
                        }
                        else
                        {
                            printf("\nCall HR, we need a new");
                            printf(" cybersecurity expert for service");
                            printf(" %d\n",(x+1));
                        }
                    }


                }
                else
                {
                    child_pid[3] = getpid();
                    command();
                }
                } 
            else 
            {
                child_pid[2]=getpid();
                IT3();
            }
         } 
        else
        {
            child_pid[1] = getpid();
            IT2();
        }
     } 
    else
    {
        child_pid[0] = getpid();
        IT1();

    }

}


void IT1(void)
{
    printf("i live");
    signal(SIGALRM,Alarmhandler);
    signal(SIGUSR1,Reconfigure  );
    signal(SIGUSR2,SNMPhandler  );
    clock_t start=0, end=0;
    static int check = 0;
    static int recona =0;
    double t= 0;
    int threat= 1;
    srand48(time(NULL));
    fprintf(fpt[1],"This is IT service 1\n");
    while(1)
    {
        printf("%d  %d   %d",reconR,alarmR,SNMPR);
        pause();
    //  alarm(1);
        if(reconR == 1)
        {
            reconR =0;
            if(recona >0)
            {
                fprintf(fpt[1],"Cannot reconfigure more than once.you are fired!");
                exit(1);
            }
            if(threat < 16)
            {
                fprintf(fpt[1],"Threat level is not critical.you are fired");
                exit(1);
            }
            fprintf(fpt[1],"Reconfiguring system to thwart attack-this may take a few seconds\n");
            recona++;
        }
        if(alarmR == 1 )
        {
            if(check >0)
            {
                t =((double)(end - start))/CLOCKS_PER_SEC;
            }

            alarmR = 0;
            if(recona >0)
            {
                threat --;
            }
            else
            {
                if (drand48() < 0.5) 
                {
                    threat++;
                } 
                else if (threat > 1 && drand48() < 0.6) 
                {
                    threat--;
                }
            }
            if(t <5)
            {
                fprintf(fpt[1],"Next report available in %f seconds\n",(5-t));
            }
            if(threat >15)
            {
                fprintf(fpt[1],"Intruder! Data stolen...");
                exit(1);
            }
            else if(threat < 10 && recona >0)
            {
                fprintf(fpt[1],"Attack averted. Mission Complete");
                exit(0);
            }

        }
        if(SNMPR == 1)
        {
            if(check == 2)
            {
                end = clock();
                t = ((double)(end - start))/CLOCKS_PER_SEC;
            }

            SNMPR = 0;
            check = 1;
            if(t <5)
            {
                fprintf(fpt[1],"Load to high. Threat is increased");
                threat++;
                t = 0;
            }
            else{
                if(threat >=10)
                    fprintf(fpt[1],"Threat level is red\n");
                else if(threat <10 && threat >=5)
                    fprintf(fpt[1],"Threat level is orange\n");
                else
                    fprintf(fpt[1],"Threat level is green\n");
            }
            if(check ==1)
            {
                start = clock();
                check = 2;
            }


        }
    }


}

2 个答案:

答案 0 :(得分:1)

您可以使用sigsuspend()系统调用使进程等待信号,并使用kill()将信号发送到进程或进程组。希望通过使用这两个系统调用,您可以编写所需的代码任务。

答案 1 :(得分:0)

您正在将wait()放在此处没有子进程的过程中

wait_r = wait(NULL);

这将导致wait()立即返回错误ECHILD,并终止第四个子进程。它的终止引发SIGCHLD导致pause()返回。