【问题标题】:Why this code stalls when calling ./prog ls ls wc 1.txt?为什么在调用 ./prog ls ls wc 1.txt 时这段代码会停止?
【发布时间】:2018-04-11 21:52:58
【问题描述】:

编译这段代码并调用时

./prog ls ls wc 1.txt

(应该是

(ls; ls) | wc > 1.txt

此代码仅在 Control-d 之后停止并立即执行。怎么了?

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

int main(int argc, char const *argv[])
{
    int fd[2];
    pipe(fd);
    if (!fork()) {
        close(fd[0]);
        dup2(fd[1], 1);
        close(fd[1]);
        if (!(fork())) {
            execlp(argv[1], argv[1], NULL);
            _exit(1);
        }
        wait(NULL);
        if (!fork()) {
            execlp(argv[2], argv[2], NULL);
            _exit(1);
        }
        wait(NULL);
    }
    close(fd[1]);
    wait(NULL);
    if (!fork()) {
        dup2(fd[0], 0);
        close(fd[0]);
        int ffd = open(argv[4], O_WRONLY | O_CREAT | O_TRUNC, 0600);
        dup2(ffd, 1);
        close(ffd);
        execlp(argv[3], argv[3], NULL);
        _exit(1);
    }
    close(fd[0]);
    wait(NULL);
    return 0;
}

【问题讨论】:

  • 我怀疑不关闭某些文件描述符或管道末端,但在我看来我对它们没问题。所以我不明白为什么它不适用于 ls ls wc(
  • 你应该设置管道 (arg[3], arg[4]) before 调用两个生产者 (ls,ls) ,并将生产者的输出连接到它们调用它们之前。
  • @wildplasser 你的评论终于让我的代码工作了。但我不明白为什么 (arg[3], arg[4]) 不能等到 ls ls 产生输出?是不是因为 ls ls 不能写入管道,没有人在读取?

标签: c unix pipe fork dup2


【解决方案1】:

你需要在第一个子进程中退出程序,否则原进程和子进程都执行底部运行wc从管道读取的代码。

或者您可以将所有代码放在else 块中,这样它就不会在子进程中运行。

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

int main(int argc, char const *argv[])
{
    int fd[2];
    pipe(fd);
    if (!fork()) {
        close(fd[0]);
        dup2(fd[1], 1);
        close(fd[1]);
        if (!(fork())) {
            execlp(argv[1], argv[1], NULL);
            _exit(1);
        }
        wait(NULL);
        if (!fork()) {
            execlp(argv[2], argv[2], NULL);
            _exit(1);
        }
        wait(NULL);
    } else {
        close(fd[1]);
        wait(NULL);
        if (!fork()) {
            dup2(fd[0], 0);
            close(fd[0]);
            int ffd = open(argv[4], O_WRONLY | O_CREAT | O_TRUNC, 0600);
            dup2(ffd, 1);
            close(ffd);
            execlp(argv[3], argv[3], NULL);
            _exit(1);
        }
        close(fd[0]);
        wait(NULL);
        return 0;
    }
}

【讨论】:

    猜你喜欢
    • 2018-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-10
    • 2017-07-26
    • 2016-12-04
    • 1970-01-01
    相关资源
    最近更新 更多