繁体   English   中英

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

[英]Processes synchronization with message queues and signals

我必须创建三个过程:

  1. 读取像1 + 3 + 5 + 12这样的表达式
  2. 检查表达式是否具有正确的语法
  3. 添加数字并显示它们

进程之间的数据使用管道机制共享。 进程同步使用消息队列和信号。我还应该能够通过控制台将信号手动发送到每个进程。

我遇到的问题是所有进程似乎都是随机运行的。 为什么会这样,这怎么了? 应该可以...

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

   #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);
}

源代码分析

存在一致性问题:

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')

由于choice是一个char ,如果您不愿意对其进行测试,则可能会错误地处理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,并且在两个条件都成立的Universe中没有已知值( NaN值是未知值)。 您确实想要这样的东西:

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

确定要发送的信号(或多或少)后,您将获得另一个重复代码块,因为您使用了P1 etc而不是数组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 ,因此条件将始终为true。 (理论上,我想,您可能输入了太多数据,以致strlen()返回的size_t溢出了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) )。 您可能无法解释浮点值的剩余部分(因为.不是整数的有效部分)。 您需要重新编写该代码。

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

我不清楚您显示的两个版本之间有什么区别; 我没有审查他们。 您应该查看如何创建MCVE( 如何创建最小,完整和可验证的示例? )或SSCCE( 简短,自包含,正确的示例 )—两个名称和相同基本思想的链接。 我不确定是否有很多代码都可以视为MCVE; 两种版本都过分杀伤力。 只需提供可编译的代码即可。


编译后

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

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

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

恭喜!

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM