`std :: shared_ptr` vs` std :: НеобязательноC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 `std :: shared_ptr` vs` std :: Необязательно

Сообщение Anonymous »

В «C ++ параллелизм в действии» от Энтони Уильямса (2012) существует безопасная очередь потока, внедренная путем хранения std :: shared_ptr как

Код: Выделить всё

template
class ThreadSafeQueue {
private:
mutable std::mutex mut;
std::queue data_queue;
std::condition_variable cv;

public:
ThreadSafeQueue() {}

void wait_and_pop(T& val) {
std::unique_lock lk(mut);
cv.wait(lk, [this] { return !data_queue.empty(); });
val = std::move(*data_queue.front());
data_queue.pop();
}

bool try_pop(T& val) {
std::lock_guard lk(mut);
if (data_queue.empty()) {
return false;
}

val = std::move(*data_queue.front());
data_queue.pop();

return true;
}

std::shared_ptr wait_and_pop() {
std::unique_lock lk(mut);
cv.wait(lk, [this] { return !data_queue.empty(); });
std::shared_ptr res = data_queue.front();
data_queue.pop();

return res;
}

std::shared_ptr try_pop() {
std::lock_guard lk(mut);
if (data_queue.empty()) {
return std::shared_ptr();
}

std::shared_ptr res = data_queue.front();
data_queue.pop();

return res;
}

void push(T val) {
std::shared_ptr data(std::make_shared(std::move(val)));
std::lock_guard lk(mut);
data_queue.push(data);
cv.notify_one();
}

bool empty() const {
std::lock_guard lk(mut);

return data_queue.empty();
}
}; // class ThreadSafeQueue
Можно ли реализовать это, используя новую std :: Необязательно ?

Код: Выделить всё

template
class ThreadSafeQueue {
private:
mutable std::mutex mut;
std::queue data_queue;
std::condition_variable cv;

public:
ThreadSafeQueue() {}

void wait_and_pop(T& val) {
std::unique_lock lk(mut);
cv.wait(lk, [this] { return !data_queue.empty(); });
val = std::move(data_queue.front());
data_queue.pop();
}

bool try_pop(T& val) {
std::lock_guard lk(mut);
if (data_queue.empty()) {
return false;
}

val = std::move(data_queue.front());
data_queue.pop();

return true;
}

T wait_and_pop() {
std::unique_lock lk(mut);
cv.wait(lk, [this] { return !data_queue.empty(); });
T res = std::move(data_queue.front());
data_queue.pop();

return res;
}

std::optional try_pop() {
std::lock_guard lk(mut);
if (data_queue.empty()) {
return std::optional();
}

std::optional res = std::move(data_queue.front());
data_queue.pop();

return res;
}

void push(T val) {
std::lock_guard lk(mut);
data_queue.push(std::move(val));
cv.notify_one();
}

bool empty() const {
std::lock_guard lk(mut);

return data_queue.empty();
}
}; // class ThreadSafeQueue
Я возвращаю std :: Необязательно in try_pop () Поскольку очередь может быть пустой, в wait_and_pop () i 'm возвращаю в значение, так как я ожидаю, пока не появится элемент в учете (так, как я не могу вернуть безопасность, поэтому я не буду возвращать значение). о том, как ведет себя wared_ptr , и, выполняя быстрый эталон, это также кажется ~ 1,3 раза быстрее, я что -то упускаю или это законно.


Подробнее здесь: https://stackoverflow.com/questions/795 ... safe-queue
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»