Если вы используете ОС UNIX, то вы можете имитировать поведение, которое вы хотите, с помощью адаптера stringstream
. Это может быть не лучший способ его выполнить, но идея состоит в том, чтобы вызвать один вызов write
, когда встречается std::endl
.
// Assume fd is in blocking mode
class fdostream : public std::ostringstream {
typedef std::ostream & (*manip_t) (std::ostream &);
struct fdbuf : public std::stringbuf {
int fd_;
fdbuf (int fd) : fd_(fd) {}
int sync() {
int r = ::write(fd_, str().data(), str().size());
str(std::string());
return (r > 0) ? 0 : -1;
}
} buf_;
std::ostream & os() { return *this; }
public:
fdostream (int fd) : buf_(fd) { os().rdbuf(&buf_); }
};
fdostream my_cout(1);
my_cout << "Hello," << " world!" << std::endl;
Это должно достичь эффекта синхронизированных записи, за счет ввода буферизации в stringstream
, а затем очищая внутреннюю string
после каждой промывки.
Для большей переносимости вы можете изменить код для использования fwrite
и указать небуферизованные записи с помощью setvbuf
. Но атомарность fwrite
будет зависеть от реализации библиотеки библиотеки.
Это может не соответствовать параметрам вашей ситуации, но вы можете потенциально перетащить все данные в отдельный рабочий процесс, который агрегирует данные (с собственной внутренней блокировкой), прежде чем сбрасывать их на стандартный вывод. – reuben
@reuben: в моем случае ваше решение является лучшим. Если вы напишете ответ, я могу выбрать его как принятый. – Pietro