multithreading - Race condition of buffered C++ streams when calling fork -- force flush? -


i have program spawns writer thread unix fork(). works fine, when buffered c++ stream has not been flushed yet, race condition 2 threads output same data. following example shows mean:

extern "c" { #include <sys/stat.h> #include <unistd.h> #include <sys/wait.h> }  #define w 10  #include <iostream>  int main(void) {    pid_t pid;    int status;    (int = 0; < (1 << w); i++) {        // spawn child after adding std::cout buffer       if (i == (1 << (w - 1))) {          // std::cout.flush(); // (1)          pid = fork();          if (!pid)             break;       }        // join child thread after while       if (i == 3 * (1 << (w - 2)))          waitpid(pid, &status, 0);        // print stuff stream       std::cout << << '\n';       // std::cout << << std::endl; // (2)    }    return exit_success; } 

so workaround tried (1) flush std::cout hand right before calling fork() (preferred solution), or (2) using std::endl when writing stream, adds unnecessarily many flush calls. although kind of works std::cout globally accessible, preferred solution (1) not work other buffered streams not globally accessible. besides, @ point might open file , forget flush then.

is there better solution problem? function flushes all buffered c++ streams?


edit

a suggested solution use fflush(nullptr) c library flush (c) streams. works std::cout , std::cerr kept in sync stdout , stderr, other c++ buffered streams not synced. demonstrates problem:

extern "c" { #include <sys/stat.h> #include <unistd.h> #include <sys/wait.h> }  #include <iostream> #include <fstream>  #define w 10  int main(void) {    pid_t pid;    int status;    std::ofstream fout("foo");     (int = 0; < (1 << w); i++) {        if (i == (1 << (w - 1))) {          fflush(nullptr);  // works std::{cout,cerr} not files          pid = fork();          if (!pid)             return exit_success;       }        if (i == 3 * (1 << (w - 2)))          waitpid(pid, &status, 0);        fout << << '\n';       std::cout << << '\n';    }    fout.close();    return exit_success; } 

on system get

$ ./a.out 1>bar; wc -l foo bar 1536 foo 1024 bar 

needless number of lines should equal.

any further ideas?

use fflush, , pass nullptr.

from man:

#include <cstdio> // adapted include c++  int fflush(file *stream); 

if stream argument null, fflush() flushes open output streams.


Comments

Popular posts from this blog

apache - PHP Soap issue while content length is larger -

asynchronous - Python asyncio task got bad yield -

javascript - Complete OpenIDConnect auth when requesting via Ajax -