C++ Linux管道、fork和execlp:如何将值写入流1

C++ Linux管道、fork和execlp:如何将值写入流1,c++,c,linux,fork,pipe,C++,C,Linux,Fork,Pipe,我使用一个函数(L)通过execlp()执行另一个程序(K)。 在K程序中,结果写入流1: write(1, (char *)&o, sizeof(int)); 由于在execlp()之后,L的剩余部分将不会执行,我如何才能得到写入流1中的结果 别问我为什么要这样做。这是一个项目的要求 我遵循了你们的建议,但现在的问题是,K程序获取参数的方式来自流(一个标准流,另一个流),我使用管道将参数写入相应的流(由父级完成) 在子exec之后,在父部分中,我从流0读取数据(K程序将其结果写回流1

我使用一个函数(L)通过
execlp()
执行另一个程序(K)。 在K程序中,结果写入流1:

write(1, (char *)&o, sizeof(int));
由于在
execlp()
之后,L的剩余部分将不会执行,我如何才能得到写入流1中的结果

别问我为什么要这样做。这是一个项目的要求

我遵循了你们的建议,但现在的问题是,K程序获取参数的方式来自流(一个标准流,另一个流),我使用管道将参数写入相应的流(由父级完成)

在子exec之后,在父部分中,我从流0读取数据(K程序将其结果写回流1)。但我能得到的是父程序写入流中的内容,而不是K程序写回的内容。 发生了什么?我需要添加另一个管道吗


谢谢

Jonathan Leffler在评论中提到的关键见解是,在调用
execlp()
之前,您需要
fork
正在运行的程序
L

在fork之后,父级继续执行剩余的
L
,子级通过调用
execlp()
,变形为程序
K
,除非出现错误,否则该程序永远不会返回

因此,“L的剩余部分不会被执行”的断言是不正确的。如果正确编写函数
L
,它将在父进程中执行

更新:由于OP让他的问题更具体了,我在这个答案后面加了一句

如果要检索子进程写入标准输出的内容(fd1),需要在fork之前创建一个新管道,并将此管道的写入端复制到子进程的标准输出中

下面是一个示例程序,它稍微修改了

#包括
#包括
#包括
#包括
#包括
#包括
int
main(int argc,char*argv[])
{
int-pipefd[2];
pid_t cpid;
焦炉;
如果(管道(管道FD)=-1){
佩罗(“管道”);
退出(退出失败);
}
cpid=fork();
如果(cpid==-1){
佩罗尔(“福克”);
退出(退出失败);
}
如果(cpid==0){/*Child写入管道*/
关闭(pipefd[0]);/*关闭未使用的读取端*/
//将管道的写入端复制到子管道的标准输出中。
dup2(pipefd[1],标准文件号);
//在这里执行程序L,它的标准输出将被管道捕获。
const char*message=“孩子正在和stdout说话!”;
写入(STDOUT_文件号、消息、strlen(消息));
写入(标准输出文件号,“\n”,1);
关闭(pipefd[1]);
_退出(退出成功);
}else{/*Parent从管道中读取子对象的标准输出*/
关闭(pipefd[1]);/*关闭未使用的写入端*/
//在这里,父进程正在读取子进程的标准输出。
while(读取(pipefd[0],&buf,1)>0)
写入(STDOUT_文件号和buf,1);
等待(NULL);/*等待子项*/
退出(退出成功);
}
}

创建管道;你用叉子叉;子对象整理管道(将管道连接到正确的位置并关闭文件描述符)并执行K;父节点整理它的管道(关闭足够多的文件描述符)并读取来自K的响应。有一本关于Linux编程的书。我建议你去it@staticx:只有一本书?你有什么建议?也许?还是史蒂文斯?或者…@Jonathan:建议,日期为1999年。我没有读过。它在亚马逊上受到好评。我唯一关心的是日期,但基本面没有太大变化。(LPI的书是2010年的;史蒂文斯是2013年的。)非常感谢!!但是出现了一个新问题:/该函数工作正常,但我正在从main调用它。在它返回到main之后,main中的cout将不再工作。我试图在调用前备份cout,然后在调用后恢复它,就像这样(),但仍然无法工作。不过,cerr将起作用。非常感谢你@fuiiii,请为一个无关的问题问一个新问题。如果此答案针对您的原始问题,请将其标记为已接受的答案。
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

int
main(int argc, char *argv[])
{
    int pipefd[2];
    pid_t cpid;
    char buf;

    if (pipe(pipefd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    cpid = fork();
    if (cpid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (cpid == 0) {    /* Child writes into the pipe */
        close(pipefd[0]);          /* Close unused read end */

        // Copy the writing end of the pipe into STDOUT for the child.
        dup2(pipefd[1], STDOUT_FILENO);

        // Execute your program L here, and its stdout will be captured by the pipe.
        const char* message = "Child is speaking to stdout!";
        write(STDOUT_FILENO, message, strlen(message));
        write(STDOUT_FILENO, "\n", 1);


        close(pipefd[1]);
        _exit(EXIT_SUCCESS);

    } else {            /* Parent reads child's stdout  from the pipe */
        close(pipefd[1]);          /* Close unused write end */

        // Here the parent process is reading the child's stdout.
        while (read(pipefd[0], &buf, 1) > 0)
            write(STDOUT_FILENO, &buf, 1);
        wait(NULL);                /* Wait for child */
        exit(EXIT_SUCCESS);
    }
}