【问题标题】:String copy using pipes使用管道复制字符串
【发布时间】:2010-01-19 10:16:01
【问题描述】:

我编写了以下代码,使用 fork 和管道将字符串“hello world”复制到另一个 char 数组,而不是使用标准库函数或标准 i/o 流。该程序编译成功,但我没有得到任何输出。甚至没有显示 printf 的输出。

# include <string.h>
# include <unistd.h>
# include <stdio.h>

char string[] = "hello world";

int main()

{

        int count, i;
        int toPar[2], toChild[2];
        char buf[256];
        pipe(toPar);
        pipe(toChild);

        if (fork() == 0)
        {
                printf("\n--- child process ---");
                close(0);
                dup(toChild[0]);
                close(1);
                dup(toPar[1]);
                close(toPar[1]);
                close(toChild[0]);
                close(toPar[0]);
                close(toChild[1]);
                for (;;)
                {
                        if ((count = read(0, buf, sizeof(buf))) == 0)
                                break;
                        printf("\nChild buf: %s", buf);
                        write(1, buf, count);
                }
        }

        printf("\n--- parent process ---");
        close(1);
        dup(toChild[1]);
        close(0);
        dup(toPar[0]);
        close(toPar[1]);
        close(toChild[0]);
        close(toPar[0]);
        close(toChild[1]);
        for (i = 0; i < 15; i++)
        {
                write(1, string, strlen(string));
                printf("\nParent buf: %s", buf);
                read(0, buf, sizeof(buf));
        }
        return 0;

   }

【问题讨论】:

    标签: c linux pipe fork dup


    【解决方案1】:

    您的 printfs 正在写入 stdout - 但在父级和子级中,您已将文件描述符 1 重定向到管道,因此 printf 输出将转到该管道。

    使用fprintf(stderr, ...) 而不是printf(...) - 然后您将能够看到输出,因为stderr 仍然指向您的终端。

    请注意,您有几个错误:

    • 子进程完成后调用_exit(0),否则会掉入父代码中;
    • write 应使用strlen(string) + 1,以便写入 nul 终止符。

    【讨论】:

    • 是的,fprintf(stderr, ...) 成功了。谢谢 !!! manav@manav-workstation:~/research/tdotuos$ ./a.out -------------- 子进程 ----------------- --- -------------- 父进程 -------- 父 buf:子 buf:hello world。父 buf: hello world... 子 buf: hello world... 父 buf: hello world... -------------- 父进程 ---------- ---------- Parent buf: hello world... 我认为正在打印“hello world”之后的额外字符,因为循环从 0 运行到 15 而不是 strlen(string)。
    【解决方案2】:

    尝试添加“\n”,例如printf("\nParent buf: %s\n", buf);

    【讨论】:

    • 我尝试在 printf() 中添加一个额外的“\n”。尽管如此,除了两个空行之外没有任何输出。 manav@manav-workstation:~/research/tdotuos$ gcc -Wall -ggdb -pedantic uopdaf.c manav@manav-workstation:~/research/tdotuos$ ./a.out manav@manav-workstation:~/research/tdotuos $
    【解决方案3】:

    我猜这些管道正在阻塞 IO,所以除非管道被其他进程关闭,否则 read 根本不会返回。那和 printf 做缓冲 IO 会阻止你得到任何输出。

    【讨论】:

    • 我尝试使用 GDB 进行调试,但它只是进入“父进程”代码并从那里退出而不打印任何内容。有没有其他工具可以对打开的“管道”进行实时分析。
    猜你喜欢
    • 2014-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-31
    相关资源
    最近更新 更多