管道和fork() - 如何通过C中的管道写入int数组?

时间:2013-04-14 13:03:04

标签: c arrays fork pipe

我正在试图用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);
}

2 个答案:

答案 0 :(得分:3)

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

如果您希望它能够以正确的方式完成工作,请执行以下操作:

发信人:

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成为。{/ p>

答案 1 :(得分:1)

-1845296639的位模式为0x92030201,假设为32位二进制补码int

因此,您使用未初始化的缓冲区获得一个字节的垃圾,以及fork ed孩子写的三个字节。

据推测,你的平台是小端的,这意味着在内存中,字节是

0x01 0x02 0x03 0x92

所以写入的字节按顺序按顺序到达,尽管期望read(...,...,3)在三个子节点写入管道的每个字节后读取三个字节是大胆的。