首页 > 解决方案 > 如何安全地使用 std::vector 和互斥锁?

问题描述

我使用多线程来读取和写入一个全局变量std::deque<int> g_to_be_downloaded_tasks,并且我使用它std::mutex来保护并发访问。但是 ThreadA 向该向量插入元素后, ThreadB 无法获取元素,

线程A

g_to_be_downloaded_tasks_mutex.try_lock();
g_to_be_downloaded_tasks.push_back(temp);
g_to_be_downloaded_tasks_mutex.unlock();

ThreadB:ThreadB在使用后得到0g_to_be_downloaded_tasks.size()

g_to_be_downloaded_tasks_mutex.try_lock();
if(g_to_be_downloaded_tasks.size() > 0)
{
    curr_task = g_to_be_downloaded_tasks.front();
}
g_to_be_downloaded_tasks_mutex.unlock();

为什么g_to_be_downloaded_tasks.size()返回 0 ?

标签: c++stdvector

解决方案


您忽略了 的结果try_lock,因此您没有有意义地使用互斥锁。由于数据竞争,您的代码具有未定义的行为。

如果您不想阻止,请使用以下结果try_lock

if (g_to_be_downloaded_tasks_mutex.try_lock()) {
    g_to_be_downloaded_tasks.push_back(temp);
    g_to_be_downloaded_tasks_mutex.unlock();
}

if(g_to_be_downloaded_tasks_mutex.try_lock() && (g_to_be_downloaded_tasks.size() > 0))
{
    curr_task = g_to_be_downloaded_tasks.front();
    g_to_be_downloaded_tasks_mutex.unlock();
}

更常见的是,生产方会等待锁,否则它正在丢弃工作

{
    std::lock_guard guard(g_to_be_downloaded_tasks_mutex);
    g_to_be_downloaded_tasks.push_back(temp);
}

推荐阅读