В моем приложении у меня есть поток событий и поток рендеринга. Я написал собственный класс потока, который может выполнять задачи (указатели на функции) с фиксированным интервалом, поэтому при необходимости я могу передавать работу между разными потоками.
Вот настройка: в потоке событий я анализирую файл это создаст модели, но прежде чем я смогу создать модели, я должен удалить старые, поэтому, естественно, я просто добавляю задачу очистки моделей следующим образом:
WindowThread::getInstance()->addTask([this]() {
this->viewport->clearModels();
});
Эта функция в конечном итоге будет выполняться оконный поток, который, кажется, работает нормально, однако при отладке с помощью valgrind он сообщает следующую ошибку: valgrind invalid read of size 8
в строке, где вызывается clearModels (). После небольшого поиска в Google проблема, похоже, заключается в том, что указатель области просмотра (или это, я точно не знаю) находится за пределами адресной области памяти оконного потока, что имеет смысл, поскольку лямбда-функция была создана в событии thread.
Есть ли способ исправить эту «ошибку», перемещая указатель / лямбду в область памяти других потоков?
FThread :: addTask (const std :: function & task) добавляет заданную задачу в очередь std :: queue (которая заранее заблокирована мьютексом) из потока, в котором она вызывается. В конце концов очередь будет обработана потоком, в который была добавлена задача.
void FThread::addTask(const std::function<void()> &task)
{
if (this->m_running && this->m_taskQueueMode != QUEUE_DISABLED)
{
this->m_taskQueueMutex.lock();
this->m_backTaskQueue->push(task);
this->m_taskQueueMutex.unlock();
}
}
void FThread::processTaskQueue()
{
this->m_taskQueueMutex.lock();
std::queue<std::function<void()>> *tmp = this->m_frontTaskQueue;
this->m_frontTaskQueue = this->m_backTaskQueue;
this->m_backTaskQueue = tmp;
this->m_taskQueueMutex.unlock();
while (!this->m_frontTaskQueue->empty())
{
this->m_frontTaskQueue->front()();
this->m_frontTaskQueue->pop();
}
}
Очередь задач настроена с двойной буферизацией, поэтому обработка текущих задач не блокирует добавление новых.
EDIT: Метод clearModels () просто удаляет каждый указатель в векторе, а затем очищает вектор.
void Viewport::clearModels()
{
if (!this->models.empty())
{
for (auto *model : this->models)
delete model;
this->models.clear();
}
this->hiddenModels.clear();
}