3

作为一个练习,我需要使用信号处理程序,并在获得信号时使用管道在两个进程之间发送一些消息。下面是我的源代码。当我运行它时,我可以让管道工作,两个进程都可以交谈,只要我在它们的主方法中调用管道(在本例中为 process1() 和 process2() )。但我想使用信号处理程序中的管道。但是现在管道不工作了。这是我得到的一些输出:

3 - 4 and 5 - 6
Segv at 8825
USR1 at 8824
898 sent to 4
130 received on 3
130

'898' 和 '130' 应该相等,但不是。我知道管道工作正常,所以我认为这与信号有关......但是什么......?

源代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>

int fd1[2], fd2[2], status;
int cpid, cpoid;

void process1() {   
    cpid = getpid();        /*What's my process ID?*/
    cpoid = cpid + 1;       /*And what's the other process ID?*/

    close(fd1[0]);
    close(fd2[1]);

    while (1) {}
}

void process2() {   
    cpid = getpid();
    cpoid = cpid - 1;

    close(fd1[1]);
    close(fd2[0]);

    raise(SIGSEGV);         /*Start with a SegV signal*/

    while (1) {}
}

/*Method to send a message to the other process, by pipe*/
void send (int msg) {
    if (cpid < cpoid) {
        write(fd1[1], &msg, 1);
        printf("%d sent to %d\n", msg, fd1[1]);
    } else {
        write(fd2[1], &msg, 1);
        printf("%d sent to %d\n", msg, fd2[1]);
    }
}

/*Method to receive a message from the other process*/
int receive () {
    int msg = 0;
    if (cpid < cpoid) {
        read(fd2[0], &msg, 1);
        printf("%d received on %d\n", msg, fd2[0]);
    } else {
        read(fd1[0], &msg, 1);
        printf("%d received on %d\n", msg, fd1[0]);
    }
    return msg;
}

/*The SegV Signal handler*/
void segvHandler() {
    int y = -1;
    printf("Segv at %d\n", cpid);
    kill(cpoid, SIGUSR1);           /*Send an USR1 Signal to the other proces*/

    while (y != 898) {
        y = receive();
        printf("%d\n", y);
    }
}

/*The Usr1 Signal handler*/
void usr1Handler() {
    int x = 898;
    printf("USR1 at %d\n", cpid);

    send(x);
}

int main (int argc, char *argv[]) {

    if (pipe(fd1) < 0) {
        fprintf (stderr, "Could not make pipe\n");
        return (EXIT_FAILURE);
    }
    if (pipe(fd2) < 0) {
        fprintf (stderr, "Could not make pipe\n");
        return (EXIT_FAILURE);
    }
    printf("%d - %d and %d - %d\n", fd1[0], fd1[1], fd2[0], fd2[1]);    /*Pipe numbers*/

    signal(SIGUSR1, usr1Handler);   /*Signal handlers*/
    signal(SIGSEGV, segvHandler);

    if (fork() != 0) {
        process1();
    } else {
        process2();
    }
    waitpid(-1, &status, 0);

    return EXIT_SUCCESS;
}
4

2 回答 2

3

基于快速浏览的一些故障。

  • printf() 不是异步信号安全的;不要在信号处理程序中调用它。

  • 您正在读取和写入 1 个字节,这很可能小于 sizeof(int)。

  • 您不能假设 PID 是连续的。在父进程中,fork() 的返回值给出了子进程的 PID。在子进程中,如果父进程在 fork() 之前存储了 getpid() 的返回值,那么你就有了;否则请参阅 getppid()。

于 2011-06-16T11:43:19.200 回答
2

As mentioned in the comments, you should not invoke printf in a signal handler, but that is probably not the problem. Unless ints are one byte on your machine, the issue is that you are not writing or reading the whole int, since you only write one byte into the pipe. (Change the code to: write( fd[ 1 ], &msg, sizeof msg ) and make the same change on the read.)

于 2011-06-16T11:32:16.700 回答