2

我一直在使用类似的东西在多线程应用程序中锁定/解锁文件

void Write_File(FILE* Input_File)
{
        flockfile(Input_File);
        Read_Stuff();
        funlock(Input_File);
}

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

4

2 回答 2

2

flockfile基本上一个互斥体,至少在 glibc 中,并且可能在所有其他平台上也是如此。因此,从某种意义上说,您已经“求助于互斥体”。如果您更改为仅使用互斥锁,则不会发生任何变化(只要对文件进行操作的所有代码路径仅在持有互斥锁时才这样做)。

重要的是不要混淆flockfile(这是一个管理单个进程的线程之间并发文件操作的互斥锁)和基于系统的咨询文件锁,就像你得到的那样flockfor fcntl(F_SETLK)

于 2013-05-03T20:11:55.487 回答
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;
于 2013-05-03T20:10:57.523 回答