4

我正在尝试学习 C 中的管道,但我被卡住了。我尝试了很多东西,但我无法获得正确的输出。

下一个程序应该显示:123

但它的输出总是方向(除非我认为):

-1845296639

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

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

    int i;
    int buff[4];
    int f[2];

    if(pipe(f) == -1)
        perror("pipe");

    for(i=0; i<3; i++){ 

        int val = i+1;
        switch(fork()){
            case -1:
                perror("fork");
                break;
            case 0:
                close(f[0]);
                write(f[1], &val, 1);
                exit(0);
                break;
            default:
                break;
        }
    }
    close(f[1]);

    for(i=0; i<3; i++)
        wait(NULL);

    read(f[0], buff, i);
    printf("%d", *buff);

    exit(0);
}
4

2 回答 2

4

管道将字节从一个地方发送到另一个地方。因此,您需要精确指定要发送的字节数。然后确保您的发送代码准确地发送这些字节,并且您的接收代码准确地期望这些字节。

如果您希望它在不必以正确方式做事的情况下工作,请执行以下操作:

发件人:

write(f[1], &val, sizeof(int));

接收者:

for (int i = 0; i < 3; ++i)
  read(f[0], &buf[i], sizeof(int));

注意还printf("%d", *buff);打印数组中的第一个元素(元素零)。

请勿将接收代码更改为read(f[0], buf, 3 * sizeof(int));. 你write不是原子的(因为你调用write了三遍)所以你不能指望你是原子的read

于 2013-04-14T13:07:49.567 回答
1

的位模式-18452966390x92030201,假设 32 位二进制补码ints。

因此,您从使用未初始化的缓冲区中得到一个字节的垃圾,以及由forked 子级写入的三个字节。

大概,您的平台是小端的,这意味着在内存中,字节是

0x01 0x02 0x03 0x92

因此写入的字节按需要按顺序到达,尽管期望read(...,...,3)在三个孩子每个向管道写入一个字节后读取三个字节是大胆的。

于 2013-04-14T13:11:41.253 回答