简体   繁体   中英

Why exit_group flushes output buffer?

From the manual page I know that:

exit() flushes output buffers while _exit , _Exit , exit_group don't.

In the code below, the content of test.log will be hello\nhello\n only if exit() was called in child process, which is the same as I tested.

But when there's no statements in child process, it will behave like it's calling exit() , the content of test.log will be hello\nhello\n too.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{

    int pid;

    FILE *fp = fopen("test.log", "w");
    fprintf(fp, "hello\n");
    pid = fork();
    if (pid == 0)
    {
        // do something
        ;
    }
    else
    {
        wait(NULL);
        exit(1);
    }
}

Through ltrace and strace I can see both parent and child called exit_group .

Since I called exit in parent, so it can be judged by using ltrace that exit will call exit_group .

But in the opposite I can't judge whether child process called exit .

Does gcc called exit in child process implicitly? It may be harmful to call exit in child process as many people said. If not, then why the buffer was flushed?

Testing gcc and glibc version:

  • gcc version 6.3.0 20170516 (Debian 6.3.0-18+deb9u1)
  • GNU C Library (Debian GLIBC 2.24-11+deb9u4) stable release version 2.24

Promoting PSkocik's comment to an answer:

Returning from main is always equivalent to calling exit() . Either way is supposed to represent "normal" termination of a process, where you want for all the data you buffered to actually get written out, all atexit() cleanup functions called, and so on.

Indeed, the C library's startup code is often written simply as exit(main(argc, argv));

If you want the "harsher" effect of _exit() or _Exit() then you have to call them explicitly. And a forked child process is a common instance where this is what you do want.

But when there's no statements in child process, it will behave like it's calling exit(), the content of test.log will be hello\nhello\n too.

You have a statement in child process (implicit):

When child process returns from main() , the C runtime makes a call to exit(0); (or better, something equivalent to exit(main(arc, argv, envp)); , indeed) that implies the flushing of buffers you are trying to avoid.

If you want to eliminate one of the hello\n s, just fflush(fp); before calling to fork() system call , as the call will duplicate fp in both processes, each with a partially full buffer the same way, and this is the reason you get the buffer contents duplicated. Or better flush all output buffers with fflush(NULL); .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM