有多个进程,所有写入相同的输出流(例如使用std::cout
),有一种方法来锁定流,以便当进程开始编写自己的消息时,它可以执行直到结束(例如用std::endl
)?
我需要一种可移植的方式。
答案 0 :(得分:2)
你运气不好。您必须使用您的taget操作系统提供的任何内容。这意味着使用全局/系统范围的互斥锁或类似lockf()
的函数。您可以使用某些第三方库来满足可移植性要求,例如Boost.Interprocess。
答案 1 :(得分:2)
目前尚不清楚它是否适合您的情况参数,但您可能会将所有数据汇集到一个单独的工作进程,该进程在将数据转储到stdout之前聚合数据(具有自己的内部锁定)。
答案 2 :(得分:1)
如果您使用的是类似操作系统的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
的原子性将取决于库函数的C实现。