在执行execlp()之后是否需要关闭管道? [英] Is closing a pipe necessary when followed by execlp()?

查看:196
本文介绍了在执行execlp()之后是否需要关闭管道?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在陈述我的问题之前,我已经阅读了一些有关堆栈溢出的相关问题,例如 pipe& ; dup在UNIX和其他几个函数中起作用,但是并没有弄清楚我的困惑.

Before stating my question, I have read several related questions on stack overflow, such as pipe & dup functions in UNIX, and several others,but didn't clarify my confusion.

首先,该代码是"Beginning Linux Programming"(第4版,第13章)中的示例代码:

First, the code, which is an example code from 'Beginning Linux Programming', 4th edition, Chapter 13:

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

int main()
{
int data_processed;
int file_pipes[2];
const char some_data[] = "123";
pid_t fork_result;

if (pipe(file_pipes) == 0)
   {
    fork_result = fork();
    if (fork_result == (pid_t)-1)
       {
        fprintf(stderr, "Fork failure");
        exit(EXIT_FAILURE);
       }

    if (fork_result == (pid_t)0)  // Child process
       {
        close(0);
        dup(file_pipes[0]);
        close(file_pipes[0]);   // LINE A
        close(file_pipes[1]);   // LINE B

        execlp("od", "od", "-c", (char *)0);
        exit(EXIT_FAILURE);
       }
    else    // parent process
       {
        close(file_pipes[0]);   // LINE C
        data_processed = write(file_pipes[1], some_data,
                               strlen(some_data));
        close(file_pipes[1]);   // LINE D
        printf("%d - wrote %d bytes\n", (int)getpid(), data_processed);
       }
   }
exit(EXIT_SUCCESS);
}

执行结果为:

momo @ xue5:〜/TestCode/IPC_Pipe $ ./a.out

momo@xue5:~/TestCode/IPC_Pipe$ ./a.out

10187-写入了3个字节

10187 - wrote 3 bytes

momo @ xue5:〜/TestCode/IPC_Pipe $ 0000000 1 2 3

momo@xue5:~/TestCode/IPC_Pipe$ 0000000 1 2 3

0000003

momo @ xue5:〜/TestCode/IPC_Pipe $

momo@xue5:~/TestCode/IPC_Pipe$

如果您评论LINE A,LINE C和LINED ,则结果与上面相同. 我了解结果,孩子通过连接到管道的自己的stdin从其父级获取数据,并将"od -c"结果发送到其stdout.

If you commented LINE A, LINE C, and LINE D, the result is the same as above. I understand the result, the child get the data from its parent through its own stdin which is connected to pipe, and send 'od -c' result to its stdout.

但是,如果您对LINE B进行评论,结果将是:

momo @ xue5:〜/TestCode/IPC_Pipe $ ./a.out

momo@xue5:~/TestCode/IPC_Pipe$ ./a.out

10436-写入了3个字节

10436 - wrote 3 bytes

momo @ xue5:〜/TestCode/IPC_Pipe $

momo@xue5:~/TestCode/IPC_Pipe$

没有"od -c"结果! 是否不执行execlp()启动的"od -c",或者其输出未定向到stdout?一种可能性是'od'的read()被阻止,因为如果注释LINE B,则子级的写文件描述符file_pipes [1]是打开的.但是注释LINE D,这会使父级的写文件描述符file_pipes [1]打开,仍然可以显示"od -c"输出.

No 'od -c' result! Is 'od -c' started by execlp() not excuted, or its output not directed to stdout? One possibility is the read() of 'od' is blocked, because the write file descriptor file_pipes[1] of child is open if you commented LINE B. But commenting LINE D, which let write file descriptor file_pipes[1] of parent open, can still have the 'od -c' output.

而且,为什么我们需要在execlp()之前关闭管道? execlp()将用"od"中的新映像替换过程映像,包括堆栈,.data,.heap,.text.这是否意味着,即使您没有像LINE A和B那样关闭子级中的file_pipes [0]和file_pipes [1],execlp()仍会破坏" file_pipes [0]和file_pipes [1]?从代码结果来看,事实并非如此.但是我在哪里错了?

And, why we need to close pipe before execlp()? execlp() will replace the process image, including stack, .data, .heap, .text with new image from 'od'. Does that mean, even if you don't close file_pipes[0] and file_pipes[1] in child as LINE A and B, file_pipes[0] and file_pipes[1] will still be 'destroyed' by execlp()? From the result by code, it is not. But where am I wrong?

非常感谢您在此付出的时间和精力~~

Thanks so much for your time and efforts here~~

推荐答案

在紧跟execlp()之后是否需要关闭管道?

Is closing a pipe necessary when followed by execlp()?

这不是严格必要的,因为它取决于管道的使用方式.但是总的来说,如果进程不需要pipe端,则应该将其关闭.

It's not strictly necessary because it depends on how the pipe is used. But in general, yes it should be closed if the pipe end is not needed by the process.

为什么我们需要在execlp()之前关闭管道? execlp()将替换过程映像

why we need to close pipe before execlp()? execlp() will replace the process image

因为文件描述符(默认情况下)在exec调用中保持打开状态.在手册页中:默认情况下,文件描述符在execve()中保持打开状态.标记为close-on-exec的文件描述符已关闭;请参阅fcntl(2)中FD_CLOEXEC的描述."

Because file descriptors (by default) remain open across exec calls. From the man page: "By default, file descriptors remain open across an execve(). File descriptors that are marked close-on-exec are closed; see the description of FD_CLOEXEC in fcntl(2)."

但是,如果您评论LINE B,...没有'od -c'结果!

However, if you commented LINE B,...No 'od -c' result!

这是因为od进程从stdin读取直到获得EOF.如果进程本身没有关闭file_pipes[1],则它将不会看到EOF,因为管道的写端不会被打开它的所有进程完全关闭.

This is because the od process reads from stdin until it gets an EOF. If the process itself does not close file_pipes[1] then it will not see an EOF as the write end of the pipe would not be fully closed by all processes that had it opened.

如果您评论LINE A,LINE C和LINE D,他的结果与上述相同

If you commented LINE A, LINE C, and LINE D, he result is the same as above

这是因为A和C处的文件描述符是管道的读取端,并且没有人被阻止等待它被关闭(如上所述). D处的文件描述符是写端,不关闭它确实会导致问题.但是,即使代码没有在该文件描述符上显式调用close,它仍将关闭,因为该进程已退出.

This is because the file descriptors at A and C are read ends of the pipe and no one will be blocked waiting for it to be closed (as described above). The file descriptor at D is a write end and not closing it would indeed cause problems. However, even though the code does not explicitly call close on that file descriptor, it will still be closed because the process exits.

这篇关于在执行execlp()之后是否需要关闭管道?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆