簡體   English   中英

如何在多個線程中僅插入向量一次

[英]how to insert vector only once in multiple thread

我有下面的代碼片段。

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將由多個線程調用,我希望g_vec僅插入一次項目,這與singleton instance有點類似。 關於singleton instance ,我發現存在DCLP問題。

問題
1.我上面的代碼段是線程安全的,是否存在DCLP問題?
2.如果不是線程安全的,該如何修改?

您的代碼存在數據爭用。

鎖外部的第一張支票與鎖內部的插入不同步。 這意味着,您可能最終會遇到一個線程(通過.empty() )讀取向量的情況,而另一個線程正在通過.insert() )寫入向量的結果, 根據定義 ,這是一個數據競爭,並導致未定義的行為。

標准以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( ... ); });
}

在您的示例中,有可能第二個可重入線程將找到一個非空的半初始化向量,這是您始終不想要的。 您應該使用一個標志,並在初始化作業完成時對其進行標記。 更好的是一個標准的,但是一個簡單的static int也會做的

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()
    }

    ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM