2012-01-19 2 views
2

У меня есть класс C++ Archive с функцией-членом extractData(). Эта функция вызывает realExtractData(), которая реализована в отдельной библиотеке C.Стандартный вывод зависает после добавления оператора fprintf() с пользовательской стандартной ошибкой

Я хочу передать функцию extractData() пару FILE * экземпляров, которые, как правило, stdout и stderr, но я хочу, чтобы обеспечить возможность указателей пользовательских файлов, а также:

class Archive { 
    public: 
     ... 
     int extractData(string id, FILE *customOut, FILE *customErr); 
     ... 
}; 

int 
Archive::extractData(string id, FILE *customOut, FILE *customErr) 
{ 
    if (realExtractData(id.c_str(), customOut) != EXIT_SUCCESS) { 
     fprintf(stderr, "something went wrong...\n"); 
     return EXIT_FAILURE; 
    } 
    return EXIT_SUCCESS; 
} 

Если я вызываю выше как указано, задержка вывода данных на стандартный вывод отсутствует. Все извлеченные данные будут посланы в стандартный вывод (stdout) почти сразу:

FILE *outFp = stdout; 
FILE *errFp = stderr; 
Archive *archive = new Archive(inFilename); 

if (archive->extractData(id, outFp, errFp) != EXIT_SUCCESS) { 
    fprintf(errFp, "[error] - could not extract %s\n", archive->getInFnCStr()); 
    return EXIT_FAILURE; 
} 

Если изменить extractData() так, что его fprintf() вызов использует customErr:

int 
Archive::extractData(string id, FILE *customOut, FILE *customErr) 
{ 
    if (realExtractData(id.c_str(), customOut) != EXIT_SUCCESS) { 
     fprintf(customErr, "something went wrong...\n"); /* <-- changed this line */ 
     return EXIT_FAILURE; 
    } 
    return EXIT_SUCCESS; 
} 

... тогда, когда я бегу двоичный, двоичный файл, похоже, зависает при обработке ввода и печати на стандартный вывод.

Если я изменяю fprintf() назад к использованию stderr и не customErr, все еще раз работать должным образом, т.е. данные сбрасываются на стандартный вывод (мой customOut) немедленно.

Это проблема буферизации? Есть ли способ исправить это?

ответ

0

«STDERR, а не customErr»

Стандартная ошибка небуферизованный, которая означает, что он печатает почти сразу. другие выходные потоки буферизуются, если вы не используете низкоуровневые вызовы ОС, а это означает, что они будут занимать больше времени для печати, если вы не сделаете сброс буфера с чем-то вроде endl: :: flush или что-то еще.

Если вы хотите пойти на звонки ОС низкого уровня, и вы работаете с Unix, проверить это:

http://www.annrich.com/cs590/notes/cs590_lecture_2.pdf

Я не читал все это, но и на ее сканирование похоже, что у него есть схожая информация с хорошим продвинутым программированием Стивенса в книге Unix, который опровергает это.

+0

Где бы я поместил вызов 'fflush()'? Если я поместил его после оператора 'fprintf()', он, похоже, не исправил зависание. –

+0

Честно говоря, я бы попытался избавиться от fprintf в пользу выполнения прямого вызова без буферизации write(), как упоминалось в этой ссылке. Это единственный способ, я думаю, это будет так же быстро, как распечатка std :: cerr/stderr. –

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

  • Нет связанных вопросов^_^