管道并不是每次在C中都给出相同的结果

管道并不是每次在C中都给出相同的结果,c,process,pipe,named-pipes,C,Process,Pipe,Named Pipes,我试图通过父进程读取文件,将内容发送到两个子进程,子进程将内容写入共享内存段。然而,每次运行时,我都会得到不同的输出,我不知道为什么 我使用两个命名管道,在写入共享内存后,父进程打开共享内存并读取每个内存的内容 第一个子对象在获取时写入内存,但第二个子对象将转换为十六进制 这是我的主要功能;假设stringtohex()工作正常 int main() { pid_t pid_1, pid_2; int fd, sd; // pipes const int SIZ

我试图通过父进程读取文件,将内容发送到两个子进程,子进程将内容写入共享内存段。然而,每次运行时,我都会得到不同的输出,我不知道为什么

我使用两个命名管道,在写入共享内存后,父进程打开共享内存并读取每个内存的内容

第一个子对象在获取时写入内存,但第二个子对象将转换为十六进制

这是我的主要功能;假设
stringtohex()
工作正常

int main()
{
    pid_t pid_1, pid_2;

    int fd, sd;     // pipes
    const int SIZE = 4096;
    const char infile[] = "in.txt";

    FILE *tp; // file pointers

    pid_1 = fork();

    if (pid_1 < 0)
    {
        fprintf(stderr, "Fork 1 failed");
        return(1);
    }

    if (pid_1 > 0)
    {
        pid_2 = fork();

        if (pid_2 < 0)
        {
            fprintf(stderr, "Fork 2 failed");
            return(1);
        }

        if (pid_2 > 0) // parent
        {
            tp = fopen(infile, "r");

            if (tp == 0)
            {
                fprintf(stderr, "Failed to open %s for reading", infile);
                return(1);
            }

            mknod(PIPE_NAME_1, S_IFIFO | 0666, 0);
            mknod(PIPE_NAME_2, S_IFIFO | 0666, 0);

            fd = open(PIPE_NAME_1, O_WRONLY);
            sd = open(PIPE_NAME_2, O_WRONLY);

            if (fd > 0 && sd > 0)
            {
                char line[300];

                while (fgets(line, sizeof(line), tp))
                {
                    int len = strlen(line);
                    int num_1 = write(fd, line, len);
                    int num_2 = write(sd, line, len);
                    if (num_1 != len || num_2 != len)
                        perror("write");
                    else
                        printf("Ch 1: wrote %d bytes\n", num_1);
                    printf("Ch 2: wrote %d bytes\n", num_2);
                }
                close(fd);
                close(sd);
            }

            fclose(tp);

            wait(NULL);

            int shm_fd = shm_open("Ch_1", O_RDONLY, 0666);

            if (shm_fd == -1)
            {
                fprintf(stderr, "Failed: Shared Memory 1");
                exit(-1);
            }

            int shm_sd = shm_open("Ch_2", O_RDONLY, 0666);

            if (shm_sd == -1)
            {
                fprintf(stderr, "Failed: Shared Memory 2");
                exit(-1);
            }

            void *ptr = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_fd, 0);

            if (ptr == MAP_FAILED)
            {
                printf("Map failed 1\n");
                return -1;
            }

            void *ptr2 = mmap(0, SIZE, PROT_READ, MAP_SHARED, shm_sd, 0);

            if (ptr2 == MAP_FAILED)
            {
                printf("Map failed 2\n");
                return -1;
            }

            fprintf(stdout, "Normal input: \n%s\n", ptr);
            fprintf(stderr, "Hexadecimal: \n%s\n", ptr2);
        }
        else // second child
        {
            // open shared memory segment
            int shm_child_2 = shm_open("Ch_2", O_CREAT | O_RDWR, 0666);

            // configure the size of the shared memory segment
            ftruncate(shm_child_2, SIZE);
            // map the pointer to the segment
            void *ptr_child_2 = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_child_2, 0);

            if (ptr_child_2 == MAP_FAILED)
            {
                printf("Map failed 3\n");
                return -1;
            }

            // configure named pipe
            mknod(PIPE_NAME_2, S_IFIFO | 0666, 0);
            sd = open(PIPE_NAME_2, O_RDONLY);

            if (sd > 0) // reading from pipe
            {
                int num;
                char s[300];

                while ((num = read(sd, s, sizeof(s))) > 0)
                {
                    // convert to hexadecimal
                    char hex[strlen(s) * 2 + 1];
                    stringtohex(s, hex);
                    // write into segment
                    sprintf(ptr_child_2, "%s", hex);
                    ptr_child_2 += strlen(s) * 2;
                }
                close(sd);
            }
            exit(0);
        }
    }
    else // first child
    {
        // create shared memory segment
        int shm_child_1 = shm_open("Ch_1", O_CREAT | O_RDWR, 0666);

        // configure the size of the shared memory segment
        ftruncate(shm_child_1, SIZE);
        // map the pointer to the segment
        void *ptr_child_1 = mmap(0, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_child_1, 0);

        if (ptr_child_1 == MAP_FAILED)
        {
            printf("Map failed 4\n");
            return -1;
        }
        // configure named pipe
        mknod(PIPE_NAME_1, S_IFIFO | 0666, 0);
        fd = open(PIPE_NAME_1, O_RDONLY);

        if (fd > 0) // reading from pipe
        {
            int num;
            char s[300];
            while ((num = read(fd, s, strlen(s))) > 0)
            {
                // write into segment
                sprintf(ptr_child_1, "%s", s);
                ptr_child_1 += strlen(s);
            }
            close(fd);
        }
        exit(0);
    }

    return 0;
}
结果如下:

正常输入: 哈伦 萨斯马兹 59900 1234 Aaaa4

十六进制: 484152554E0A7361736D617A0A35393930300A313233340A416161

正常输入: 哈伦 萨斯马兹 asmaz59900 1234

Aaaa

十六进制:
484152554E0A7361736D617A0A35393930300A0A313233340A416161FF03我发现你的代码真的不可读。我建议不要创建这么长的函数——在小的可读部分之间拆分函数
read
返回
ssize\u t
,而不是
int
strlen
返回
size\u t
,而不是
int
。请使用一致的缩进
strlen
-
s
是否真的以零结尾?例如,在
read(fd,s,strlen(s))
-
s
未初始化。您不能假设从
read(fd,s,sizeof(s))
读取的内容将以零结尾。您应该使用
read
返回值来确定数据的长度。我已经习惯了C语言编程,我知道代码的结构很混乱,但我正在努力专注于这项任务。谢谢你的建议。我不认为我在
while((num=read(sd,s,sizeof(s))>0){//convert to hexadecimal char hex[strlen(s)*2+1];
-为什么
strlen(s)
工作?你不会在管道中写入零字节。你的代码:
while((num=read(sd,s,sizeof))>0){char hex[strlen(s)*2+1];
应在数组定义中使用
num*2+1
。应告知您的
stringtohex()
要转换多少字节。可能存在错误,因为
stringtohex()
不是一个字符串,而是一个没有空字节标记结尾的字节数组。你知道当你“假设”某个东西起作用时会发生什么吗?它让你和我都很难堪。你没有显示代码来转储读取的内容,或者由
stringtohex()生成的内容,例如,因此你不知道发生了什么。为什么要使用
mknod()
要创建FIFO而不是
mkfifo()
Harun
sasmaz
59900
1234
Aaaa