简体   繁体   中英

How can I use std::vector safely with mutex?

I use multithreading to read and write a global variable std::deque<int> g_to_be_downloaded_tasks , and I use std::mutex to protect concurrent access. but ThreadB can not get element after ThreadA inserts an element to this vector,

ThreadA

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 gets 0 after using g_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();

Why g_to_be_downloaded_tasks.size() returns 0?

You are ignoring the result of try_lock , so you aren't meaningfully using a mutex. Your code has undefined behaviour because of a data race.

If you never want to block, use the result of 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();
}

More commonly, the producing side would wait for the lock, otherwise it is discarding work

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM