2013-07-23 3 views
0

Я наблюдаю какое-то странное поведение, когда я использую 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(), производя эти странные поведения ... Если у кого-то есть идеи о том, что может быть причиной этого, я был бы признателен за помощь!

ответ

0

Я думаю, что я понял, что создал этот ответ для потомков/любого, кто наткнулся на эти вопросы, ища ответа.

Я наблюдал это поведение в boost 1.40, но когда я попробовал его с использованием boost 1.46, все делалось ожидаемым образом в всех случаях, т.е.:

Log opened. 
Parent exiting. 
Hello World! 

Так что мое предположение прямо сейчас, что это было на самом деле ошибка в импульсе, который был установлен где-то между версией 1.41-1.46. Я ничего не видел в примечаниях к выпуску, которые сделали для меня совершенно очевидным, что они обнаружили, что & исправил ошибку, но возможно, что в примечаниях к выпуску обсуждаются некоторые основные причины этой ошибки, и я не смог установить соединение между это основная причина и этот сценарий.

В любом случае, решение, похоже, заключается в установке ускорительной версии> = 1.46

Смежные вопросы