解决该问题的正确方法是什么?

例如,我有一个名为write.c的程序,该程序具有4个子进程,并且这些子进程将其PID写入单个全局命名管道。

另一个名为read.c的程序应读取此PID。

我有一种类似下面的方法,但是这种方法存在一些问题。它无法读取所有PID,有时无法读取其中的3个,有时甚至可以读取其中的2个,我认为存在同步问题,如何解决此问题? :

writer.c

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

int main(){
    int fd;
    char * myfifo = "/tmp/myfifo"; //FIFO file
    char buffer[50];

    mkfifo(myfifo, 0666); //creating the FIFO

    for(int i=0;i<4;i++){ //creating 4 child process
        if(fork() == 0) {
            fd = open(myfifo, O_WRONLY); //each child process opens the FIFO for writing their own PID.

            sprintf(buffer, "%d", getpid()); //each child process gets pid and assign it to buffer
            printf("write:%s\n", buffer);  // each child process prints to see the buffer clearly

            write(fd, buffer, strlen(buffer)+1); //each child process writes the buffer to the FIFO
            close(fd);

            exit(0);
        }
    }
    for(int i=0;i<4;i++) { //waiting the termination of all 4 child processes.
        wait(NULL);
    }
    //parent area
}


reader.c

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <time.h>
#include <string.h>
#include <fcntl.h>

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

    int fd1;

    // FIFO file path
    char * myfifo = "/tmp/myfifo";

    // Creating the named file(FIFO)
    mkfifo(myfifo, 0666);

    char str1[80]; //str2[80];
    while (1)
    {
        // First open in read only and read
        fd1 = open(myfifo,O_RDONLY);
        read(fd1, str1, 80);

        // Print the read string and close
        printf("read: %s\n", str1);
        close(fd1);
    }
}

最佳答案

这行将空字节写入fifo:

write(fd, buffer, strlen(buffer)+1);


因此,如果管道中有两个pid,则会读取以下字符串:

1234\02345\0


并且printf将仅打印到第一个\0

1234


要解决此问题,将PID转换为二进制文件而不是格式化和解析文本会更容易:

作家:

    if(fork() == 0) {
        fd = open(myfifo, O_WRONLY);
        pid_t pid = getpid();
        write(fd, &pid, sizeof(pid));
        close(fd);
        exit(0);
    }


读者:

fd1 = open(myfifo,O_RDONLY);
pid_t pid;
while (1) // whatever is your termination condition
{
    read(fd1, &pid, sizeof(pid));
    printf("read: %d\n", pid);
}
close(fd1);

07-24 09:51
查看更多