【问题标题】:Closing file child descriptors after killing parent?杀死父级后关闭文件子描述符?
【发布时间】:2018-02-19 18:08:16
【问题描述】:

杀死父进程时如何关闭子文件描述符?

我创建了一个执行以下操作的程序:

  1. 分叉 2 个子进程。

  2. 进程 1 是读取器。它从 STDIN_FILENO 读取并使用 scanf/printf 写入 STDOUT_FILENO。但我使用 dup2 重定向到命名管道(我们称之为 npipe)。

  3. 进程 2 是写入器。我将 STDIN_FILENO 重定向到 npipe,以便我可以使用该管道中的 scanf 。我将 STDOUT_FILENO 重定向到另一个名为“output_file”的文件,以便我可以使用 printf 进行写入。

读/写在 while(1) 循环中完成;

while(1){
scanf("%s",word);
printf("%s",word);
}

如果我使用 CTRL+C(向父级发送 SIGTERM 信号),任何写入“output_file”的数据都会丢失。里面什么都没有。我认为这是因为我在打开文件时杀死了进程?

我使用了一个词,在读取时会停止两个子进程;在这种情况下,我的“输出文件”中确实包含所有内容。

使用 SIGTERM 时如何关闭文件? / 我能否以某种方式强制我的进程写入“output_file”,以便在突然关闭时不会丢失数据?

我尝试在每次写入后关闭和打开文件。仍然丢失所有写入的数据?这是因为重定向吗?

void read_from_pipe(void)
{
    char command[100];
    int new_fd = open(pipe_name,O_RDONLY,0644);
    int output_file = open("new_file",O_CREAT|O_WRONLY|O_APPEND,0644);

    dup2(new_fd,0);
    dup2(output_file,1);
    while(1)
    {   
        scanf("%s",command);
        if(strcmp(command,"stop")==0)
        {
            close(output_file);
            close(new_fd);
            exit(0);
        }
        else
        printf("%s ",command); 
        close(output_file);
        output_file = open("new_file",O_CREAT|O_WRONLY|O_APPEND,0644);
    }    
}

设法附加正确的信号处理程序,但即使我关闭我的文件,数据仍然没有写入!这是为什么呢?

【问题讨论】:

  • 您需要安装一个信号处理程序,以确保您的文件在退出时关闭。
  • 试图这样做,但似乎孩子们没有注意到它。另外,我不知道如何为同一个信号的两个孩子制作不同的处理程序。
  • 如果您在安装信号处理程序后 fork 进程,您的子进程将拥有信号处理程序。然后,您可以在您的父级中安装另一个处理程序,将信号传播给子级。此外,您可以使用 FSYNC 标志打开文件。
  • 是的,有道理!那将是一个自然的解决方案;好的,但是我尝试了下一件事,但又出现了问题……每次写入后我都关闭了文件,但文件中仍然没有写入数据..
  • 父亲”?为什么不使用标准的“parent”?

标签: c linux posix


【解决方案1】:

您的问题(可能)与关闭文件描述符无关,而是与刷新 FILE 指针有关。请注意,文件指针和文件描述符是两个不同的东西。

您调用printf,它不会写入STDOUT_FILENO(文件描述符),它会写入stdout(文件指针),通常只是缓冲数据,直到它有理由将其写入底层文件描述符(STDOUT_FILENO)。

因此,您需要确保写入 stdout 的数据实际上已写入 STDOUT_FILENO。最简单的方法是在 printf 调用之后粘贴 fflush(stdout); 以手动刷新它,让您可以在写入内容时进行细粒度控制。或者,您可以调用setbuf(stdout, 0); 使标准输出无缓冲,因此每次写入都会立即刷新。

【讨论】:

  • 感谢您的回答!听起来这可能是我的问题。稍后编辑:好吧,我尝试使用 fflush(stdout);和 setbuf(stdout,0);但奇怪的是,它并没有强制写入数据。
  • 他也可以用O_FSYNC打开文件,这样可以确保在任何write()调用返回之前将数据写入磁盘。
  • @sturcotte06 这只会影响文件描述符和写入,而不影响 FILE 指针及其缓冲,因此可能与 OP 的实际问题无关。
  • 是的,你是对的,我以为他使用的是 POSIX 接口。但是 stdin 和 stdout 是流。我的坏;)
  • 嗨,似乎 setbuf(stdout, 0);有效,但前提是它在父进程中使用。我不明白为什么 fflush 在 printf 之后不起作用/为什么 setbuf in child 不起作用。
猜你喜欢
  • 2012-04-29
  • 1970-01-01
  • 2014-07-04
  • 2017-09-05
  • 1970-01-01
  • 2017-02-18
  • 2014-02-06
  • 2013-05-23
  • 2021-03-12
相关资源
最近更新 更多