有多个进程,都写在同一个输出流上(例如 with std::cout
),有没有办法锁定流,以便当一个进程开始编写自己的消息时,它可以一直执行到最后(例如 with std::endl
)?
我需要一种便携的方式来做到这一点。
你运气不好。您将不得不使用您的taget OS 提供的任何东西。这意味着使用全局/系统范围的互斥锁或lockf()
类似功能。您可以使用一些 3rd 方库来满足可移植性要求,例如Boost.Interprocess。
目前尚不清楚它是否适合您的情况参数,但您可能会将所有数据汇集到一个单独的工作进程,该进程在将数据转储到标准输出之前聚合数据(具有自己的内部锁定)。
如果您使用的是类似 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;
这应该达到同步写入的效果,代价是缓冲输入到 a 中stringstream
,然后string
在每次刷新后清除内部。
为了获得更大的可移植性,您可以修改代码以使用fwrite
,并使用 指定无缓冲写入setvbuf
。但是,原子性fwrite
将取决于库函数的 C 实现。