处理与消息队列和信号的同步

时间:2015-06-13 22:56:23

标签: c linux

我必须创建三个流程:

  1. 阅读表达式,如1 + 3 + 5 + 12
  2. 检查表达式是否具有正确的语法
  3. 添加数字并显示它们
  4. 使用管道机制共享进程之间的数据。进程同步使用消息队列和信号。我也应该能够通过控制台手动向每个进程发送信号。

    我遇到的问题是所有进程似乎都是随机运行的。为什么,这里有什么问题?它应该工作......

    这是正确编译的整个代码:

       #include <stdio.h>
    #include <unistd.h>
    #include <signal.h> 
    #include <sys/types.h>
    #include <sys/ipc.h> 
    #include <sys/msg.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    #define SIZEBUFF 256
    
    // Signal handling for each process
    void h_sig1(int signo);
    void h_sig2(int signo);
    void h_sig3(int signo);
    void h_S4(int signo);
    
    // Processes functions
    void process1(void);
    void process2(void);
    void process3(void);
    
    // helper functions
    bool isInteger(double val);
    
    static pid_t P1, P2, P3; // PIDs for each process
    
    int P; // parent PID
    int pfd12[2], pfd23[2]; // Pipes between processes 1-2 and 2-3
    int providePIDY1[2], providePIDY2[2]; // provide all PIDs to 1/2 process
    
    // message in message queue
    typedef struct 
    {
        long type;
        int sigNum;
    } message;
    
    int queue_ID;
    
    int main(void)
    {
        P = getpid();
    
        // Message queue created
        if ((queue_ID = msgget(IPC_PRIVATE,IPC_CREAT|0666)) < 0)
        {
            printf("msgget\n");
            return 1;
        }
    
        if((P1 = fork()) == 0)
        {
            P1 = getpid();
            process1();
        }
        else if((P2 = fork()) == 0)
        {
            P2 = getpid();
            process2();
        }
        else if((P3 = fork()) == 0)
        {
            P3 = getpid();
            process3();
        }
        else
        { // Sending signals from parent through operator
    
            // Sending PIDs to process 1
            close(providePIDY1[0]);
            write(providePIDY1[1], &P, sizeof(int));
            write(providePIDY1[1], &P1, sizeof(int));
            write(providePIDY1[1], &P2, sizeof(int));
            write(providePIDY1[1], &P3, sizeof(int));
            close(providePIDY1[1]);
    
            // Sending PIDs to process 2
            close(providePIDY2[0]);
            write(providePIDY2[1], &P, sizeof(int));
            write(providePIDY2[1], &P1, sizeof(int));
            write(providePIDY2[1], &P2, sizeof(int));
            write(providePIDY2[1], &P3, sizeof(int));
            close(providePIDY2[1]);
    
            printf("\nProgram options:\n");
            printf("Send signal - 's'(send)\n");
            printf("Display processes PIDs 'p'(pids)\n");
            printf("Quit program - 'q'(quit)\n");
    
            char choice, choice2, choice3;
    
            while(1)
            {
                choice = getchar();
    
                if(choice == 's')
                {        
                    printf("Which process is receiving the signal - 1, 2, or 3?: ");
                    choice2 = getchar();
                    choice2 = getchar();
                    printf("\n");
    
                    if((choice2 < 1) && (choice2 > 3))
                    {
                        printf("No such process!");
                        continue;
                    }
    
                    printf("What signal to send?:\n");
                    printf("1-S1(end execution)\n2-S2(pause execution)\n3-S3(renew execution)?\n ");
                    printf("Choice: ");
                    choice3 = getchar();
                    choice3 = getchar();
                    switch(choice2)
                    {
                        case '1':  //nie można przechwycić sygnałów SIGKILL oraz SIGSTOP (zabicia oraz zatrzymania)
                            if(choice3 == '1') { kill(0,SIGCONT); kill(P1,SIGUSR1); }
                            if(choice3 == '2') kill(P1,SIGTSTP);
                            if(choice3 == '3') { kill(0,SIGCONT); kill(P3,SIGALRM); }
                            break;
                        case '2': 
                              if(choice3 == '1') { kill(0,SIGCONT); kill(P2,SIGUSR1); }
                              if(choice3 == '2') kill(P2,SIGTSTP); 
                              if(choice3 == '3') { kill(0,SIGCONT); kill(P3,SIGALRM); }
                            break;
                        case '3': 
                              if(choice3 == '1') { kill(0,SIGCONT); kill(P3,SIGUSR1); }
                              if(choice3 == '2') kill(P3,SIGTSTP);
                              if(choice3 == '3') { kill(0,SIGCONT); kill(P3,SIGALRM); }
                            break;
                        default: printf("No such operation!!! \n\n");
                    }
                }
    
                if(choice == 'p')
                {
                    // do something
                }
    
                if(choice == 'q')
                {
                    // do something
                }
           }
    
        }
    }
    
    void process1(void)
    {
        // Receiving PIDs
        close(providePIDY1[1]);
        read(providePIDY1[0], &P, sizeof(int));
        read(providePIDY1[0], &P1, sizeof(int));
        read(providePIDY1[0], &P2, sizeof(int));
        read(providePIDY1[0], &P3, sizeof(int));
        close(providePIDY1[0]);
    
        struct sigaction act1;
    
        act1.sa_handler = h_sig1;
        sigemptyset(&act1.sa_mask);
        act1.sa_flags = 0;
        sigaction(SIGUSR1, &act1, 0);
        sigaction(SIGTSTP, &act1, 0);
        sigaction(SIGALRM, &act1, 0);
    
        struct sigaction act;
        act.sa_handler = h_S4;
        sigemptyset(&act.sa_mask);
        act.sa_flags = 0;
        sigaction(SIGINT, &act, 0);
    
        // do something
    }
    
    void process2(void)
    {
        close(providePIDY2[1]);
        read(providePIDY2[0], &P, sizeof(int));
        read(providePIDY2[0], &P1, sizeof(int));
        read(providePIDY2[0], &P2, sizeof(int));
        read(providePIDY2[0], &P3, sizeof(int));
        close(providePIDY2[0]);
    
        struct sigaction act2;
        act2.sa_handler = h_sig2;
        sigemptyset(&act2.sa_mask);
        act2.sa_flags = 0;
        sigaction(SIGUSR1, &act2, 0);
        sigaction(SIGTSTP, &act2, 0);
        sigaction(SIGALRM, &act2, 0);
    
        struct sigaction act;
        act.sa_handler = h_S4;
        sigemptyset(&act.sa_mask);
        act.sa_flags = 0;
        sigaction(SIGINT, &act, 0);
    
        // do something
    }
    
    void process3(void)
    {
        struct sigaction act3;
    
        act3.sa_handler = h_sig3;
        sigemptyset(&act3.sa_mask);
        act3.sa_flags = 0;
        sigaction(SIGUSR1, &act3, 0);
        sigaction(SIGTSTP, &act3, 0);
        sigaction(SIGALRM, &act3, 0);
    
        struct sigaction act;
        act.sa_handler = h_S4;
        sigemptyset(&act.sa_mask);
        act.sa_flags = 0;
        sigaction(SIGINT, &act, 0);
    
        // do something
    }
    
    void h_sig1(int signo)
    {
        message msg;
    
        msg.type = P2;
        msg.sigNum = signo;
    
        kill(P2, SIGINT);
    
        // send type of receiving signal to message queue
        msgsnd(queue_ID, &msg, sizeof(msg.sigNum), 0);
    
        msg.type = P3;
        kill(P3, SIGINT);
        msgsnd(queue_ID, &msg, sizeof(msg.sigNum), 0);
    
        if(signo == SIGUSR1)
        {    
        }
    
        if(signo == SIGTSTP)
        {
        }    
    
        if(signo == SIGALRM)
        {
        }    
    }
    
    void h_sig2(int signo)
    {
        message msg;
    
        msg.type = P1;
        msg.sigNum = signo;
    
        kill(P1, SIGINT);
    
        // send type of receiving signal to message queue
        msgsnd(queue_ID, &msg, sizeof(msg.sigNum), 0);
    
        msg.type = P3;
        kill(P3, SIGINT);
        msgsnd(queue_ID, &msg, sizeof(msg.sigNum), 0);
    
        if(signo == SIGUSR1)
        {    
        }
    
        if(signo == SIGTSTP)
        {
        }    
    
        if(signo == SIGALRM)
        {
        }    
    }
    
    void h_sig3(int signo)
    {
        message msg;
    
        msg.type = P1;
        msg.sigNum = signo;
    
        kill(P1, SIGINT);
    
        // send type of receiving signal to message queue
        msgsnd(queue_ID, &msg, sizeof(msg.sigNum), 0);
    
        msg.type = P2;
        kill(P2, SIGINT);
        msgsnd(queue_ID, &msg, sizeof(msg.sigNum), 0);
    
        if(signo == SIGUSR1)
        {    
        }
    
        if(signo == SIGTSTP)
        {
        }    
    
        if(signo == SIGALRM)
        {
        }    
    }
    
    void h_S4(int signo)
    {
        int res;
        message msg;
    
        printf("\nProcess with PID=%d received signal S4", getpid());
    
        if(signo == SIGINT)
        {
            res = msgrcv(queue_ID, &msg, sizeof(msg.sigNum), msg.type, 0);
    
            if(res >= 0)
            {            
                if(msg.sigNum == SIGUSR1)
                {
    
                }
                if(msg.sigNum == SIGTSTP)
                {
    
                }
                if(msg.sigNum == SIGALRM)
                {
                }
            }
        }
    }
    

    长版,编译:

    #include <stdio.h>
    #include <unistd.h>
    #include <signal.h> 
    #include <sys/types.h>
    #include <sys/ipc.h> 
    #include <sys/msg.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    #define SIZEBUFF 200
    
    // Signal handling for each process
    void h_sig1(int signo);
    void h_sig2(int signo);
    void h_sig3(int signo);
    
    void h_S4(int signo); // signal handling for the 4th signal
    
    // Processes functions
    void process1(void);
    void process2(void);
    void process3(void);
    
    // helper functions
    bool isInteger(double val);
    
    static pid_t P1, P2, P3; // PIDs for each process
    
    int P; // parent PID
    int pfd12[2], pfd23[2]; // Pipes between processes 1-2 and 2-3
    int providePIDY1[2], providePIDY2[2]; // provide all PIDs to 1/2 process
    
    // message in message queue
    typedef struct 
    {
        long type;
        int sigNum;
    } message;
    
    int queue_ID;
    
    int main(void)
    {
        P = getpid();
    
        if (pipe(pfd12) == -1)
        {
            perror("pipe failed");
            exit(1);
        }
        if (pipe(pfd23) == -1)
        {
            perror("pipe failed");
            exit(1);
        }
    
        // Message queue created
        if ((queue_ID = msgget(IPC_PRIVATE,IPC_CREAT|0666)) < 0)
        {
            printf("msgget\n");
            return 1;
        }
    
        if (pipe(providePIDY1) == -1)
        {
            perror("pipe failed");
            exit(1);
        }
        if (pipe(providePIDY2) == -1)
        {
            perror("pipe failed");
            exit(1);
        }
    
        if((P1 = fork()) == 0)
        {
            P1 = getpid();
            process1();
        }
        else if(P1 < 0)
        {
            perror("fork failed");
            exit(2);
        }
        else if((P2 = fork()) == 0)
        {
            P2 = getpid();
            process2();
        }
        else if(P2 < 0)
        {
            perror("fork failed");
            exit(2);
        }
        else if((P3 = fork()) == 0)
        {
            P3 = getpid();
            process3();
        }
        else if(P3 < 0)
        {
            perror("fork failed");
            exit(2);
        }
        else
        { // Sending signals from parent through operator
    
            // Sending PIDs to process 1
            close(providePIDY1[0]);
            write(providePIDY1[1], &P, sizeof(int));
            write(providePIDY1[1], &P1, sizeof(int));
            write(providePIDY1[1], &P2, sizeof(int));
            write(providePIDY1[1], &P3, sizeof(int));
            close(providePIDY1[1]);
    
            // Sending PIDs to process 2
            close(providePIDY2[0]);
            write(providePIDY2[1], &P, sizeof(int));
            write(providePIDY2[1], &P1, sizeof(int));
            write(providePIDY2[1], &P2, sizeof(int));
            write(providePIDY2[1], &P3, sizeof(int));
            close(providePIDY2[1]);
    
            printf("\nProgram options:\n");
            printf("Send signal - 's'(send)\n");
            printf("Display processes PIDs 'p'(pids)\n");
            printf("Quit program - 'q'(quit)\n");
    
            char choice, choice2, choice3;
    
            while(1)
            {
                choice = getchar();
    
                if(choice == 's')
                {        
                    printf("Which process is receiving the signal - 1, 2, or 3?: ");
                    choice2 = getchar();
                    choice2 = getchar();
                    printf("\n");
    
                    if((choice2 < 1) && (choice2 > 3))
                    {
                        printf("No such process!");
                        continue;
                    }
    
                    printf("What signal to send?:\n");
                    printf("1-S1(end execution)\n2-S2(pause execution)\n3-S3(renew execution)?\n ");
                    printf("Choice: ");
                    choice3 = getchar();
                    choice3 = getchar();
                    switch(choice2)
                    {
                        case '1':  //nie można przechwycić sygnałów SIGKILL oraz SIGSTOP (zabicia oraz zatrzymania)
                            if(choice3 == '1') { kill(0,SIGCONT); kill(P1,SIGUSR1); }
                            if(choice3 == '2') kill(P1,SIGTSTP);
                            if(choice3 == '3') { kill(0,SIGCONT); kill(P3,SIGALRM); }
                            break;
                        case '2': 
                              if(choice3 == '1') { kill(0,SIGCONT); kill(P2,SIGUSR1); }
                              if(choice3 == '2') kill(P2,SIGTSTP); 
                              if(choice3 == '3') { kill(0,SIGCONT); kill(P3,SIGALRM); }
                            break;
                        case '3': 
                              if(choice3 == '1') { kill(0,SIGCONT); kill(P3,SIGUSR1); }
                              if(choice3 == '2') kill(P3,SIGTSTP);
                              if(choice3 == '3') { kill(0,SIGCONT); kill(P3,SIGALRM); }
                            break;
                        default: printf("No such operation!!! \n\n");
                    }
                }
    
                if(choice == 'p')
                {
                    printf("\n<Processes PIDs:>\n");
                    printf("P(initial process)=%d\n",P);
                    printf("P1(process 1)=%d\n",P1);
                    printf("P2(process 2)=%d\n",P2);
                    printf("P3(process 3)=%d\n\n",P3);
                }
    
                if(choice == 'q')
                {
                    printf("\n<Quitting program>\n");
                    msgctl(queue_ID, IPC_RMID, 0);
                    kill(0, SIGKILL);
                }
           }
    
        }
    }
    
    void process1(void)
    {
        int dataSize;
        char buff[SIZEBUFF];
    
        // Receiving PIDs
        close(providePIDY1[1]);
        read(providePIDY1[0], &P, sizeof(int));
        read(providePIDY1[0], &P1, sizeof(int));
        read(providePIDY1[0], &P2, sizeof(int));
        read(providePIDY1[0], &P3, sizeof(int));
        close(providePIDY1[0]);
    
        printf("\n<Process 1 execution in progress>\n");
    
        /*SIGACTION*/
    
        struct sigaction act1;
    
        act1.sa_handler = h_sig1;
        sigemptyset(&act1.sa_mask);
        act1.sa_flags = 0;
        sigaction(SIGUSR1, &act1, 0);
        sigaction(SIGTSTP, &act1, 0);
        sigaction(SIGALRM, &act1, 0);
    
        struct sigaction act;
        act.sa_handler = h_S4;
        sigemptyset(&act.sa_mask);
        act.sa_flags = 0;
        sigaction(SIGINT, &act, 0);
    
    
        close(pfd12[0]);
        while(1)
        {
            printf("Provide expr: ");
            scanf("%s", buff);
            if(strcmp(buff, "0") == 0)
                break;
    
            dataSize = strlen(buff) + 1; // plus NULL
            if(dataSize > 0)
                write(pfd12[1], &dataSize, sizeof(int));
            write(pfd12[1], &buff, sizeof(char)*dataSize);
        }
    
        dataSize = 0; // info that there's no more data
        write(pfd12[1], &dataSize, sizeof(int));
    
        close(pfd12[1]);
    
        printf("\n---Process 1 finished execution---\n");
    
        exit(0);
    }
    
    void process2(void)
    {
        int dataSize;
        char buff[SIZEBUFF];
        char *token, *end;
        int number;
        const char delim[2] = "+";
    
        //Odebranie pidow
        close(providePIDY2[1]);
        read(providePIDY2[0], &P, sizeof(int));
        read(providePIDY2[0], &P1, sizeof(int));
        read(providePIDY2[0], &P2, sizeof(int));
        read(providePIDY2[0], &P3, sizeof(int));
        close(providePIDY2[0]);
    
        printf("\n<Process 2 execution in progress>\n");
    
        /*SIGACTION*/
        struct sigaction act2;
        act2.sa_handler = h_sig2;
        sigemptyset(&act2.sa_mask);
        act2.sa_flags = 0;
        sigaction(SIGUSR1, &act2, 0);
        sigaction(SIGTSTP, &act2, 0);
        sigaction(SIGALRM, &act2, 0);
    
        struct sigaction act;
        act.sa_handler = h_S4;
        sigemptyset(&act.sa_mask);
        act.sa_flags = 0;
        sigaction(SIGINT, &act, 0);
    
        close(pfd12[1]);
    
        read(pfd12[0], &dataSize, sizeof(int));
        if(dataSize > 0)
        {
            sleep(3);
    
            read(pfd12[0], buff, dataSize);
            token = strtok(buff, delim);
            while( token != NULL )
            {
                number = strtol(token, &end, 0);
                if(!isInteger(number))
                    break;
            }
        }
    
        close(pfd12[0]);
    
        // Sending result to process 3
        close(pfd23[0]);
        write(pfd23[1], &buff, sizeof(int));
        close(pfd23[1]);
    
        printf("\n---Process 2 finished execution---\n");
    }
    
    void process3(void)
    {
        int sum = 0;
        char buff[SIZEBUFF];
        char* token, *end;
        int number;
        const char delim[2] = "+";
    
        /*SIGACTION*/
        struct sigaction act3;
    
        act3.sa_handler = h_sig3;
        sigemptyset(&act3.sa_mask);
        act3.sa_flags = 0;
        sigaction(SIGUSR1, &act3, 0);
        sigaction(SIGTSTP, &act3, 0);
        sigaction(SIGALRM, &act3, 0);
    
        struct sigaction act;
        act.sa_handler = h_S4;
        sigemptyset(&act.sa_mask);
        act.sa_flags = 0;
        sigaction(SIGINT, &act, 0);
    
        printf("\n<Process 3 execution in progress>");
        close(pfd23[1]);
    
        read(pfd23[0], &buff, sizeof(int));
    
        token = strtok(buff, delim);
    
        while( token != NULL )
        {
            number = strtol(token, &end, 0);
            sum += number;
        }
    
        printf("Sum = %d\n", sum);
    
        close(pfd23[0]);
    
        printf("\n---Process 3 finished execution ---\n");
    
        printf("\n---Program finished execution---\n");
        kill(getppid(),SIGKILL);
    
    }
    
    /*******************************************************************************************************/
    /****************************************SIGNAL HANDLING (S1-S3)***********************************************/
    /*******************************************************************************************************/
    void h_sig1(int signo)
    {
        message msg;
    
        msg.type = P2;
        msg.sigNum = signo;
    
        kill(P2, SIGINT);
    
        // send type of receiving signal to message queue
        msgsnd(queue_ID, &msg, sizeof(msg.sigNum), 0);
    
        msg.type = P3;
        kill(P3, SIGINT);
        msgsnd(queue_ID, &msg, sizeof(msg.sigNum), 0);
    
        if(signo == SIGUSR1)
        {    
            printf("\nProcess 1 received signal S1\n");
            printf("Terminating parent process!\n");
            kill(getppid(), SIGKILL);
            printf("Terminating process 1!\n");
            kill(getpid(), SIGKILL);
        }
    
        if(signo == SIGTSTP)
        {
            printf("\nProcess 1 received signal S2\n");
            printf("Pausing process 1!\n");
            kill(getpid(), SIGSTOP);
        }    
    
        if(signo == SIGALRM)
        {
            printf("\nProcess 1 received signal S3\n");
            printf("Renewing execution of process 1!\n");
            kill(getpid(), SIGCONT);
        }    
    }
    
    void h_sig2(int signo)
    {
        message msg;
    
        msg.type = P1;
        msg.sigNum = signo;
    
        kill(P1, SIGINT);
    
        // send type of receiving signal to message queue
        msgsnd(queue_ID, &msg, sizeof(msg.sigNum), 0);
    
        msg.type = P3;
        kill(P3, SIGINT);
        msgsnd(queue_ID, &msg, sizeof(msg.sigNum), 0);
    
        if(signo == SIGUSR1)
        {    
            printf("\nProcess 2 received signal S1\n");
            printf("Terminating parent process!\n");
            kill(getppid(), SIGKILL);
            printf("Terminating process 2!\n");
            kill(getpid(), SIGKILL);
        }
    
        if(signo == SIGTSTP)
        {
            printf("\nProcess 2 received signal S2\n");
            printf("Pausing process 2!\n");
            kill(getpid(), SIGSTOP);
        }    
    
        if(signo == SIGALRM)
        {
            printf("\nProcess 2 received signal S3\n");
            printf("Renewing execution of process 2!\n");
            kill(getpid(), SIGCONT);
        }    
    }
    
    void h_sig3(int signo)
    {
        message msg;
    
        msg.type = P1;
        msg.sigNum = signo;
    
        kill(P1, SIGINT);
    
        // send type of receiving signal to message queue
        msgsnd(queue_ID, &msg, sizeof(msg.sigNum), 0);
    
        msg.type = P2;
        kill(P2, SIGINT);
        msgsnd(queue_ID, &msg, sizeof(msg.sigNum), 0);
    
        if(signo == SIGUSR1)
        {    
            printf("\nProcess 3 received signal S1\n");
            printf("Terminating parent process!\n");
            kill(getppid(), SIGKILL);
            printf("Terminating process 3!\n");
            kill(getpid(), SIGKILL);
        }
    
        if(signo == SIGTSTP)
        {
            printf("\nProcess 3 received signal S2\n");
            printf("Pausing process 3!\n");
            kill(getpid(), SIGSTOP);
        }    
    
        if(signo == SIGALRM)
        {
            printf("\nProcess 3 received signal S3\n");
            printf("Renewing execution of process 3!\n");
            kill(getpid(), SIGCONT);
        }    
    }
    
    /*******************************************************************************************************/
    /****************************************Handling S4 signal***********************************/
    /*******************************************************************************************************/
    
    void h_S4(int signo)
    {
        int res;
        message msg;
    
        printf("\nProcess with PID=%d received signal S4", getpid());
    
        if(signo == SIGINT)
        {
            res = msgrcv(queue_ID, &msg, sizeof(msg.sigNum), msg.type, 0);
    
            if(res >= 0)
            {            
                if(msg.sigNum == SIGUSR1)
                {
                        printf("Terminating process\n");
                        kill(getpid(),SIGKILL);
    
                }
                if(msg.sigNum == SIGTSTP)
                {
                        printf("Pausing process\n");
                        kill(getpid(),SIGSTOP);
    
                }
                if(msg.sigNum == SIGALRM)
                {
                        printf("Renewing process\n");
                        kill(getpid(),SIGCONT);
    
                }
            }
        }
    }
    
    bool isInteger(double val)
    {
        int truncated = (int)val;
        return (val == truncated);
    }
    

1 个答案:

答案 0 :(得分:2)

源代码分析

存在一致性问题:

static pid_t P1, P2, P3; // PIDs for each process

int P; // parent PID

为什么Pint代替pid_t?为什么它是全局而不是static?为什么P代替P0?全部应该是阵列吗?

static pid_t P[4];

(使用数组会有好处!)

应该在多次调用的函数中重复:

// Sending PIDs to process 1
close(providePIDY1[0]);
write(providePIDY1[1], &P, sizeof(int));
write(providePIDY1[1], &P1, sizeof(int));
write(providePIDY1[1], &P2, sizeof(int));
write(providePIDY1[1], &P3, sizeof(int));
close(providePIDY1[1]);

// Sending PIDs to process 2
close(providePIDY2[0]);
write(providePIDY2[1], &P, sizeof(int));
write(providePIDY2[1], &P1, sizeof(int));
write(providePIDY2[1], &P2, sizeof(int));
write(providePIDY2[1], &P3, sizeof(int));
close(providePIDY2[1]);

请注意,还有重复,因为P值不是数组。还有一种可能的可移植性责任; pid_t的大小不必与int相同。

检查输入时出现问题:

choice = getchar();

if(choice == 's')

由于choicechar,您可能会错误地处理EOF - 如果您不愿意对其进行测试。您还在输入中留下换行符(至少),并且不要跳过输入中的前导空格。阅读一系列数据(fgets()或POSIX),您可能会做得更好 readline())然后使用if (sscanf(buffer, " %c", &choice) != 1) { …handle error… }获取角色。

您的下一个输入块很奇怪:

printf("Which process is receiving the signal - 1, 2, or 3?: ");
choice2 = getchar();
choice2 = getchar();
printf("\n");

if((choice2 < 1) && (choice2 > 3))

第一个输入读取换行符(假设没有尾随空格等),第二个输入读取'1''2''3'。但是,您测试输入值是否小于1且大于3,并且在两个条件都为真的情况下,宇宙中没有已知值(NaN值是未知值)。你真的想要这样的东西:

if (choice2 < '1' || choice2 > '3')

在您确定要发送哪个信号(或多或少)后,您有另一个重复代码块,因为您使用了P1等而不是数组P

您的子进程中存在重复代码块,例如读取进程号的代码。这些也应该是一个功能。信号处理设置也应该是一个功能,尽管我没有花很多时间检查不同过程功能之间的差异和相似之处。

主要问题

你说代码应该是处理算术表达式。您有关于信号处理的主程序循环读取选择,但您似乎也尝试读取表达式process1()。这是坏消息;不确定哪个进程可以读取任何给定的输入。

回到小东西

你有:

dataSize = strlen(buff) + 1; // plus NULL
if(dataSize > 0)
    write(pfd12[1], &dataSize, sizeof(int));
write(pfd12[1], &buff, sizeof(char)*dataSize);

测试有点无意义; strlen()可以返回的最小值为0,因此dataSize中的最小值为1,因此条件始终为真。 (从理论上讲,我想,您可以输入如此多的数据,size_t返回的strlen()溢出int dataSize,但您没有为此分配足够的空间问题 - 在此之前你的代码会遇到其他问题。)

process2()中,此代码很奇怪:

    token = strtok(buff, delim);
    while( token != NULL )
    {
        number = strtol(token, &end, 0);
        if(!isInteger(number))
            break;
    }

当您使用int number;扫描字符串时,strtol()在任何情况下都不会是非整数。您有溢出的风险(例如,在64位Unix系统上sizeof(int) != sizeof(long))。您有可能无法解释浮点值的残余(因为.不是整数的有效部分)。您需要重做该代码。

信号处理代码中有很多重复;它应该被重构,以便您需要更少的功能。从长远来看,它会更容易理解。当结果接近单个程序中代码的克隆时,复制&#39; n&#39; n&#39;编辑是一种非常糟糕的编程方式。

我不清楚您展示的两个版本之间的差异;我没有仔细检查过它们。您应该了解如何创建MCVE(How to create a Minimal, Complete, and Verifiable Example?)或SSCCE(Short, Self-Contained, Correct Example) - 两个名称和链接用于相同的基本思想。我不确定这两行代码是否合格为MCVE;两个版本都是矫枉过正。只需提供可编辑的代码。

编译后

我在使用GCC 5.1.0运行Mac OS X 10.10.3的Mac上编译了第二块代码(保存在名为procsync.c的文件中),并使用命令行:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
>     -Wold-style-definition -Werror procsync.c -o procsync
$

令我非常惊讶的是,这些代码在非常严格的选项下编译而没有任何抱怨 - 这是我在SO上的代码中很少看到的。

<强>恭喜!

(但仍有其他问题需要担心。)

相关问题