Как безопасно передать владение атомарным необработанным указателем, чтобы переместить только объект в другой поток? - PullRequest
0 голосов
/ 24 мая 2018

Необходимо поставить в очередь Task (не копируемый, только перемещаемый) из функции Enqueue, а затем делегировать обработку функции Process в отдельном потоке.

Enqueue функция вызывается несколькими потоками.

Да, это может быть сделано с помощью очереди, но на данный момент мне нужен только один task.compare_and_exchange выглядит лучше, чем полноценная очередь с несколькими производителями и одним потребителем или блокировка очереди одного производителя и одного потребителя.

// multiple enqueuers
bool Enqueue(Task task) {
    auto task_ptr = new Task{std::move(task)};
    Task* expected = nullptr;
    while(!this->enqueud_task_.compare_exchange_strong(expected, task_ptr)) {
        if (!somecondition) {
            delete task_ptr;
            return false; 
        }
    }
    return true;        
}

// process
void Process() {
    auto task = this->enqueud_task_.load();
    if (task) {
        auto t = task;
        this->do_store(std::move(*t)); // Store the moved object to internal data structure.
        delete t;
        this->enqueud_task_ = nullptr; 
    }
}

Проблема в том, что я выделяю новую Task который перенесен из исходного задания.Это заставляет меня вручную вызывать delete.

std::atomic<std::unique_ptr<Task>> не является допустимым типом, а также std::atomic<Task>, так как Task не может быть легко скопирован.

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