简体   繁体   中英

how to insert vector only once in multiple thread

I have below code snippet.

std::vector<int> g_vec;

void func()
{
    //I add double check to avoid thread need lock every time.
    if(g_vec.empty())
    {
       //lock
       if(g_vec.empty())
       {
          //insert items into g_vec
       }
       //unlock
    }

    ...
}

func will be called by multiple thread, and I want g_vec will be inserted items only once which is a bit similar as singleton instance . And about singleton instance , I found there is a DCLP issue.

Question :
1. My above code snippet is thread safe, is it has DCLP issue?
2. If not thread safe, how to modify it?

Your code has a data race.

The first check outside the lock is not synchronized with the insertion inside the lock. That means, you may end up with one thread reading the vector (through .empty() ) while another thread is writing the vector (through .insert() ), which is by definition a data race and leads to undefined behavior.

A solution for exactly this kind of problem is given by the standard in form of call_once .

#include<mutex>

std::vector<int> g_vec;
std::once_flag g_flag;

void func()
{
    std::call_once(g_flag, [&g_vec](){ g_vec.insert( ... ); });
}

In your example, it could happen that second reentrant thread will find a non empty half initialized vector, that it's something that you won`t want anyway. You should use a flag, and mark it when initialization job is completed. Better a standard one, but a simple static int will do the job as well

std::vector<int> g_vec;

void func()
{
    //I add double check to avoid thread need lock every time.
    static int called = 0;
    if(!called)
    {
       lock()
       if(!called)
       {
          //insert items into g_vec
          called = 1;
       }
       unlock()
    }

    ...
}

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