输出流锁定用于多进程同步?

时间:2012-06-30 18:26:13

标签: c++ stl process stream locking

有多个进程,所有写入相同的输出流(例如使用std::cout),有一种方法来锁定流,以便当进程开始编写自己的消息时,它可以执行直到结束(例如用std::endl)?

我需要一种可移植的方式。

3 个答案:

答案 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实现。