我获得了关于顺序编程和锁定编程的代码。我必须分析差异,但我不确定某些代码在做什么。代码如下,子弹中也提到了我不理解的部分。
感谢您的阅读,任何帮助将不胜感激!
<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
答案 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,则会在mutex
和empty()
方法中出现编译错误。所以从技术上讲,锁没有被禁用,但你的程序形成不良。
由于我对此缺乏了解,为什么not_full和not_empty不需要变量?
很简单,因为它们用于非const方法
所以不需要让它们变得可变。如果你在const方法中使用它们中的任何一个,并且你想在full()
上使用非const方法,那么你需要使它们变得可变。