我一直在使用类似的东西在多线程应用程序中锁定/解锁文件
void Write_File(FILE* Input_File)
{
flockfile(Input_File);
Read_Stuff();
funlock(Input_File);
}
我想将这些例程转换为使用流。我找不到与流一起使用的类似命令。有没有办法在不使用互斥锁的情况下锁定文件流?
我一直在使用类似的东西在多线程应用程序中锁定/解锁文件
void Write_File(FILE* Input_File)
{
flockfile(Input_File);
Read_Stuff();
funlock(Input_File);
}
我想将这些例程转换为使用流。我找不到与流一起使用的类似命令。有没有办法在不使用互斥锁的情况下锁定文件流?
flockfile
基本上是一个互斥体,至少在 glibc 中,并且可能在所有其他平台上也是如此。因此,从某种意义上说,您已经“求助于互斥体”。如果您更改为仅使用互斥锁,则不会发生任何变化(只要对文件进行操作的所有代码路径仅在持有互斥锁时才这样做)。
重要的是不要混淆flockfile
(这是一个管理单个进程的线程之间并发文件操作的互斥锁)和基于系统的咨询文件锁,就像你得到的那样flockf
or fcntl(F_SETLK)
。
您可以围绕 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;