У меня проблема с созданием вектора блокировки очередей в C ++ - PullRequest
1 голос
/ 27 июня 2019

Я пытаюсь написать простую программу, которая создает и использует определенное количество (переменная - это параметр, передаваемый из командной строки) блокирующих очередей. Чтобы легко получить к ним доступ, я подумал о создании вектора очередей.

Я использую g ++ - 8 для компиляции программы. Моя очередь предоставлена ​​моим профессором, поэтому я не могу внести никаких изменений в ее код.

Вот код, который я разработал:

blocking_queue.hpp

    #ifndef SKYLINE_BLOCKING_QUEUE_HPP
    #define SKYLINE_BLOCKING_QUEUE_HPP

    #include <iostream>
    #include <mutex>
    #include <condition_variable>
    #include <deque>
    #include <vector>
    #include <chrono>
    #include <cstddef>
    #include <math.h>
    #include <string>
    #include <thread>


    using namespace std::literals::chrono_literals;

    //
    // needed a blocking queue
    // here is a sample queue.
    //

    template <typename T>
    class blocking_queue
    {
    private:
    std::mutex d_mutex;
    std::condition_variable d_condition;
    std::deque<T> d_queue;
    public:

    blocking_queue(){}

    void push(T const& value) {
        {
            std::unique_lock<std::mutex> lock(this->d_mutex);
            d_queue.push_front(value);
        }
        this->d_condition.notify_one();
    }

    T pop() {
        std::unique_lock<std::mutex> lock(this->d_mutex);
        this->d_condition.wait(lock, [=]{return !this->d_queue.empty(); });
        T rc(std::move(this->d_queue.back()));
        this->d_queue.pop_back();
        return rc;
    }

    bool is_empty() {
        std::unique_lock<std::mutex> lock(this->d_mutex);
        this->d_condition.wait(lock, [=]{return !this->d_queue.empty(); });
        printf("ADDED A INT\n");
        return false;
    }

    int size() {
        std::unique_lock<std::mutex> lock(this->d_mutex);
        return(d_queue.size());
    }

    };

    #endif // SKYLINE_BLOCKING_QUEUE_HPP

test.cpp

    int main(char argc, char* argv[]) {
        nw = atoi(argv[0]);
        vector<blocking_queue<int>> myVector;

        for(int i = 0; i < nw; i++) {
            myVector.emplace_back();             
        }

    }

Когда я пытаюсь скомпилировать программу, g ++ выдает следующую ошибку:

error: use of deleted function ‘blocking_queue<int>::blocking_queue(blocking_queue<int>&&)’
  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ./test.cpp:10:
./blocking_queue.hpp:28:7: note: ‘blocking_queue<int>::blocking_queue(blocking_queue<int>&&)’ is implicitly deleted because the default definition would be ill-formed:
 class blocking_queue
       ^~~~~~~~~~~~~~
./blocking_queue.hpp:28:7: error: use of deleted function ‘std::mutex::mutex(const std::mutex&)’
In file included from /usr/include/c++/8/mutex:43,
                 from ./blocking_queue.hpp:9,
                 from ./test.cpp:10:
/usr/include/c++/8/bits/std_mutex.h:97:5: note: declared here
     mutex(const mutex&) = delete;
     ^~~~~
In file included from ./test.cpp:10:
./blocking_queue.hpp:28:7: error: use of deleted function ‘std::condition_variable::condition_variable(const std::condition_variable&)’
 class blocking_queue
       ^~~~~~~~~~~~~~

Как мне решить проблему?

Ответы [ 2 ]

3 голосов
/ 27 июня 2019

Если вам просто нужно создать вектор из nw элементов, вы можете сделать следующее:

std::vector<blocking_queue<int>> myVector(nw);

Использование emplace_back может работать, но при выполнении emplace_back vectorвозможно, потребуется изменить размер и изменить размер может вызвать копии между старым буфером и новым буфером.Смотрите C ++ vector emplace_back вызывает конструктор копирования .Насколько я знаю, если у вас есть noexcept ctor перемещения, vector будет использовать его вместо копирования, но я не знаю, является ли это гарантированной оптимизацией по сравнению со стандартом того, что может выбрать разработчик.Несмотря на это, ваш класс не кажется подвижным из-за некоторых его членов, а именно condition_variable и mutex.Поэтому использование этого конкретного объекта внутри вектора может быть проблематичным, зависит от вашего варианта использования.

Если вам нужно изменить размер контейнера, вы можете:

  1. Сохранить vector и использовать unique_ptr объекта queue для хранения элементов внутри вектора
  2. Используйте std::list, который не должен требовать копирования объектов при изменении размера, поскольку это связанный список.

В обоих случаях вы можете потерять производительность

0 голосов
/ 27 июня 2019

Попробуйте использовать emplace_back() вместо push_back().

push_back() использует конструктор копирования, который, кажется, был удален.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...