如何在没有互斥锁的情况下锁定文件流

时间:2013-05-03 19:30:15

标签: c++ multithreading locking

我一直在使用类似

之类的东西锁定/解锁多线程应用程序中的文件
void Write_File(FILE* Input_File)
{
        flockfile(Input_File);
        Read_Stuff();
        funlock(Input_File);
}

我想将这些例程转换为使用流。我找不到与stream一起使用的类似命令。有没有办法在不使用互斥锁的情况下锁定文件流?

2 个答案:

答案 0 :(得分:2)

flockfile基本上一个互斥锁,至少在glibc中,并且可能在其他所有平台上。所以从某种意义上说,你已经在使用互斥量"。如果改为仅使用互斥锁,则不会改变任何内容(只要在文件上运行的所有代码路径都只在保持互斥锁的情况下这样做)。

重要的是不要将flockfile(在单个进程的线程之间管理并发文件操作的互斥锁)与基于系统的建议文件锁混淆,因为您需要{{1 }或flockf

答案 1 :(得分:1)

您可以围绕C ++ I / O流样式接口包装C样式流。下面的示例让您了解如何使用ostringstream实现一个:

class lockedostream_impl : public std::ostringstream
{
    friend class lockedostream;
    struct buf_t : public std::stringbuf {
        FILE *f_;
        buf_t (FILE *f) : f_(f) { flockfile(f_); }
        ~buf_t () { funlockfile(f_); }
        int sync () {
            int r = (f_ ? -(fputs(str().c_str(), f_) == EOF) : 0);
            str(std::string());
            return r;
        }
    } buf_;
    std::ostream & os () { return *this; }
    lockedostream_impl (FILE *f) : buf_(f) { os().rdbuf(&buf_); }
};


class lockedostream {
    typedef std::ostream & (*manip_t) (std::ostream &);
    mutable lockedostream_impl impl_;
public:
    lockedostream (FILE *f) : impl_(f) {}
    template <typename T>
    const lockedostream & operator << (const T &t) const {
        impl_.os() << t;
        return *this;
    }
    const lockedostream & operator << (manip_t m) const {
        impl_.os() << m;
        return *this;
    }
};

您可以根据需要更改锁定原语,但我仍然希望使用flockfile()funlockfile()。有了这个,您可以编写如下代码:

lockedostream(f)
    << some_stuff_to_be_written
    << some_other_stuff
    << std::endl;