1

有多个进程,都写在同一个输出流上(例如 with std::cout),有没有办法锁定流,以便当一个进程开始编写自己的消息时,它可以一直执行到最后(例如 with std::endl)?

我需要一种便携的方式来做到这一点。

4

3 回答 3

2

你运气不好。您将不得不使用您的taget OS 提供的任何东西。这意味着使用全局/系统范围的互斥锁或lockf()类似功能。您可以使用一些 3rd 方库来满足可移植性要求,例如Boost.Interprocess

于 2012-06-30T18:29:10.947 回答
2

目前尚不清楚它是否适合您的情况参数,但您可能会将所有数据汇集到一个单独的工作进程,该进程在将数据转储到标准输出之前聚合数据(具有自己的内部锁定)。

于 2012-07-01T12:41:30.513 回答
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;

这应该达到同步写入的效果,代价是缓冲输入到 a 中stringstream,然后string在每次刷新后清除内部。

为了获得更大的可移植性,您可以修改代码以使用fwrite,并使用 指定无缓冲写入setvbuf。但是,原子性fwrite将取决于库函数的 C 实现。

于 2012-06-30T21:12:05.487 回答