Я наблюдаю какое-то странное поведение, когда я использую file_sink
(в boost :: iostreams), а затем fork()
дочерний процесс.Странное поведение с boost file_sink при forking
Ребенок продолжает ту же самую кодовую базу, то есть без вызова exec()
, потому что это делается как часть процесса демонализации. Разумеется, мой полный код полностью демонзирует процесс, но я пропустил те шаги, которые являются излишними для того, чтобы восстановить поведение.
Следующий код является упрощенный пример, который демонстрирует поведение:
using namespace std;
namespace io = boost::iostreams;
void daemonize(std::ostream& log);
int main (int argc, char** argv)
{
io::stream_buffer<io::file_sink> logbuf;
std::ostream filelog(&logbuf);
//std::ofstream filelog;
// Step 1: open log
if (argc > 1)
{
//filelog.open(argv[1]);
logbuf.open(io::file_sink(argv[1]));
daemonize(filelog);
}
else
daemonize(std::cerr);
return EXIT_SUCCESS;
}
void daemonize(std::ostream& log)
{
log << "Log opened." << endl;
// Step 2: fork - parent stops, child continues
log.flush();
pid_t pid = fork(); // error checking omitted
if (pid > 0)
{
log << "Parent exiting." << endl;
exit(EXIT_SUCCESS);
}
assert(0 == pid); // child continues
// Step 3: write to log
sleep(1); // give parent process time to exit
log << "Hello World!" << endl;
}
Если я запускаю это без аргументов (например, ./a.out
), так что он входит в stderr
, то я получаю ожидаемый выход:
Log opened.
Parent exiting.
Hello World!
Однако, если я что-то вроде ./a.out temp; sleep 2; cat temp
тогда я получаю:
Log opened.
Hello World!
Итак, родитель как-то больше не записывает файл после вилки. Это головоломка №1.
Предположим, что я просто переместил io::stream_buffer<io::file_sink> logbuf;
за пределы main, так что это глобальная переменная. Делая это, и просто работает ./a.out
дает тот же ожидаемый выход, как и в предыдущем случае, но запись в файл (например, температура) теперь дает новое загадочное поведение:
Log opened.
Parent exiting.
Log opened.
Hello World!
В строке, пишет «Вход открыт.» до fork()
, поэтому я не понимаю, почему это должно появиться дважды на выходе. (Я даже поставил явный flush()
непосредственно перед fork()
, чтобы убедиться, что строка вывода не просто буферизована, а затем буфер скопирован во время fork()
, а затем обе копии в конечном итоге покраснели в поток ...) Итак, это головоломка # 2.
Конечно, если я закомментировать весь fork()
процесс (весь раздел, обозначенный как «Шаг 2»), то он ведет себя, как ожидается, как для файла и stderr
вывода, и независимо от того, является ли logbuf
глобальным или локальным для main()
.
Кроме того, если я переключаю filelog
быть ofstream
вместо stream_buffer<file_sink>
(см закомментированных строк в main()
), то он также ведет себя, как ожидается, как для файлов и stderr
вывода, и независимо от того, filelog
/logbuf
являются глобальными или локальными для main()
.
Так что кажется, что это взаимодействие между file_sink
и fork()
, производя эти странные поведения ... Если у кого-то есть идеи о том, что может быть причиной этого, я был бы признателен за помощь!