Ich bekam diesen Code für die sequentielle Programmierung und Lock-Programmierung. Ich muss den Unterschied analysieren, aber ich bin mir nicht sicher, was ein Teil des Codes tut. Der Code ist unten, und die Teile, die ich nicht verstehe, werden auch in den Kugeln erwähnt.
- Wirkung von Stichwort: Veränderliche
- Eine andere Antwort sagt, dass Stackoverflow wandelbar ein const modifiziert zu sein
erlaubt, aber ich sehe nicht, was das mit diesem Projekt zu tun hat - Was das ist Effekt des Entfernens "veränderbar" in diesem Programm? Deaktiviert es die Sperren?
- Eine andere Antwort sagt, dass Stackoverflow wandelbar ein const modifiziert zu sein
- Mutable für not_full und not_empty
- meinen Mangel an Verständnis für diese Förderung, warum wandelbar ist nicht für not_full und not_empty erforderlich?
Vielen Dank für das Lesen, wäre jede Hilfe dankbar!
<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
Ich denke, es ist zu ermöglichen, den Mutex auch in 'const' Methoden zu sperren – user463035818
' mutable' hat nichts mit Sperren zu tun; Wird es aus diesem Code entfernt, führt dies höchstens dazu, dass es nicht kompiliert werden kann. –
http://en.cppreference.com/w/cpp/language/cv kann hilfreich sein. –