C ++中可以做些什么?

时间:2017-12-07 17:50:17

标签: c++ locking mutex


我获得了关于顺序编程和锁定编程的代码。我必须分析差异,但我不确定某些代码在做什么。代码如下,子弹中也提到了我不理解的部分。

  • 关键字的效果:可变
    • 另一个StackOverflow回答说mutable允许const为
      已修改,但我看不出与该项目有什么关系
    • 在此程序中删除“mutable”有什么影响?它是否禁用 锁?
  • 对于not_full和not_empty可变
    • 由于我对此缺乏了解,为什么not_full和not_empty不需要变数?

感谢您的阅读,任何帮助将不胜感激!

<pre><code>
    #ifndef LOCKEDBUFFER_H
    #define LOCKEDBUFFER_H

    #include <memory>
    #include <mutex>
    #include <condition_variable>
    #include <atomic>

    #include "optional.h"

    template <typename T>
    class locked_buffer {
    public:
      // Creates buffer of size n
      locked_buffer(int n) :
        size_{n},
        buf_{new optional<T>[size_]}
      {
      }

      // Remove copy constructor
      locked_buffer(const locked_buffer &) = delete;

      // Destructor (default generated)
      ~locked_buffer() = default;

      // Gets buffer size
      int size() const noexcept {
        return size_;
      }

      // Checks if buffer is empty
      bool empty() const noexcept {
        std::lock_guard<std::mutex> l{mut_};
        return is_empty();
      }

      // Checks if buffer is full
      bool full() const noexcept {
        std::lock_guard<std::mutex> l{mut_};
        return is_full();
      }

      // Put an optional value in the queue
      void put(const optional<T> & x);

      // Get a value from the queue
      optional<T> get();

    private:
      // Next circular position to position p
      int next_position(int p) const noexcept {
        return p + ((p+1>=size_)?(1-size_):1);
      }

      // Check if buffer is empty without locking
      bool is_empty() const noexcept {
        return (next_read_ == next_write_);
      }

      // Check if buffer is full without locking
      bool is_full() const noexcept {
        const int next = next_position(next_write_);
        return next == next_read_;
      }

    private:
      const int size_;
      const std::unique_ptr<optional<T>[]> buf_;
      int next_read_ = 0;
      int next_write_ = 0;

      mutable std::mutex mut_;
      std::condition_variable not_full_;
      std::condition_variable not_empty_;
    };


    template <typename T>
    void locked_buffer<T>::put(const optional<T> & x) 
    {
      using namespace std;
      unique_lock<mutex> l{mut_};
      not_full_.wait(l, [this] { return !is_full(); });
      buf_[next_write_] = x;
      next_write_ = next_position(next_write_);
      not_empty_.notify_one();
    }

    template <typename T>
    optional<T> locked_buffer<T>::get()
    {
      using namespace std;
      unique_lock<mutex> l{mut_};
      not_empty_.wait(l, [this] { return !is_empty(); });
      auto res = buf_[next_read_];
      next_read_ = next_position(next_read_);
      not_full_.notify_one();
      return res;
    }

    #endif

1 个答案:

答案 0 :(得分:3)

让我们一步一步地完成它。

  

另一个StackOverflow回答说mutable允许使用const   已修改,但我不知道这与该项目有什么关系

这确实适用于你的班级。 你有这种方法。

project1

lock guard期望非const对象引用,因为bool empty() const noexcept { std::lock_guard<std::mutex> l{mut_}; return is_empty(); } 将更改互斥锁。 但由于您的方法是const,因此无法以非const方式访问任何成员。这里是mutable发挥作用的地方。

  

在此程序中删除“mutable”有什么影响?它会禁用锁吗?

如果从lock_guard中删除mutable,则会在mutexempty()方法中出现编译错误。所以从技术上讲,锁没有被禁用,但你的程序形成不良。

  

由于我对此缺乏了解,为什么not_full和not_empty不需要变量?

很简单,因为它们用于非const方法 所以不需要让它们变得可变。如果你在const方法中使用它们中的任何一个,并且你想在full()上使用非const方法,那么你需要使它们变得可变。