【问题标题】:how to lock a file stream without a mutex如何在没有互斥锁的情况下锁定文件流
【发布时间】:2013-05-03 19:30:15
【问题描述】:

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

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

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

【问题讨论】:

  • 您是否只是试图阻止同一进程中的其他线程写入文件,或者“系统中的任何进程”?这些是截然不同的问题,解决方案也大不相同(或不可能,取决于系统的要求和架构)。
  • 你真的在写输出之前锁定了一个输入文件吗?
  • @user315052 我真的想阅读,我编辑了代码来反映这一点。
  • @MatsPetersson:我希望它不受同一进程中的线程的影响
  • 好的,然后使用mutex,正如 Celada 下面解释的那样。它会做正确的事,并且工作得非常好。

标签: c++ multithreading locking


【解决方案1】:

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

重要的是不要将flockfile(管理单个进程的线程之间的并发文件操作的互斥锁)与基于系统的咨询文件锁混淆,就像您使用flockffcntl(F_SETLK) 一样.

【讨论】:

    【解决方案2】:

    您可以围绕 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;
    

    【讨论】:

      猜你喜欢
      • 2012-06-05
      • 1970-01-01
      • 2018-06-10
      • 2015-04-14
      • 1970-01-01
      • 2014-02-28
      • 1970-01-01
      • 2021-07-01
      • 2018-09-20
      相关资源
      最近更新 更多