繁体   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