C++ 使用std::atomic时锁定线程

C++ 使用std::atomic时锁定线程,c++,multithreading,c++11,C++,Multithreading,C++11,所以我主要有一个std::atomic。它被发送到生成随机数的线程: void wind_thread(std::atomic<int>* wind) { while(total_planes < max_plane ) { *wind = random(1, 360); } } void wind\u线程(标准::原子*风) { while(总平面流行音乐(); } 总平面数++; } } } land_线程中的wind很好,但是当

所以我主要有一个
std::atomic
。它被发送到生成随机数的线程:

void wind_thread(std::atomic<int>* wind)
{
    while(total_planes < max_plane )
    {
        *wind = random(1, 360);
    }
}
void wind\u线程(标准::原子*风)
{
while(总平面<最大平面)
{
*风=随机(1360);
}
}
其他两个线程获取此变量并使用它执行操作,下面是一个示例:

void land_thread(std::atomic<int>* wind, std::queue<Plane> *land, Runway *north_south, Runway *east_west)
{
    while(total_planes <= max_plane)
    {
        if(land->size() == 0){}
        else
        {
            std::lock_guard<std::mutex> guard(my_mutex);

            std::cout << "Plane " << land->front().get_plane_id()
            << " landed on " << wind_string(wind) << " Wind was: "
            << *wind << std::endl;

            land->front().set_details(wind_string(wind));

            if((*wind >= 46 && *wind <= 135) || (*wind >= 226 && *wind <= 315))
            {
                east_west->land(land->front());
                land->pop();
            }
            else
            {
                north_south->land(land->front());
                land->pop();
            }

            total_planes++;

        }
    }
}
无效着陆线程(标准::原子*风,标准::队列*着陆,跑道*南北,跑道*东西)
{
而(总平面大小()==0){
其他的
{
std::锁定保护(我的互斥);
std::cout front());
土地->流行音乐();
}
总平面数++;
}
}
}
land_线程中的wind很好,但是当我将它传递给接受
std::atomic*x
wind_string()
函数时,它会得到一个新值


如果我在wind线程上加上一个锁,它可以正常工作,但我认为使用
std::atomic
的全部意义在于,如果只有一个线程在向它写入,我就不需要使用锁。是因为我将它传递给线程之外的函数吗?我一直在网上四处寻找,我能找到的只是我不需要锁。如果有人能解释它为什么会这样,或者有一个更深入了解原子行为的链接,我们将不胜感激。谢谢。

因为在
的原子设置周围并没有锁,所以绝对不能保证在某个时间看到
的值。原子提供给您的所有信息是,在设置时,该值将被传播,因此在重置之前读取该值的任何人都将获得设置值。它还保证在设置这个原子int之前设置的任何东西都是可见的

但是,在您的示例中,当您在另一个线程中持有锁时,没有任何东西可以阻止修改
wind

1 你的风线程将在100%使用率下使用整个线程,只是为了保持你的风的随机性。在那里添加一些
sleep
s,以避免对CPU造成不必要的压力或使程序减速。
或者仅仅考虑按需生成随机值。(见附件)

2. 原子只会使对数据本身的访问原子化

            if((*wind >= 46 && *wind <= 135) || (*wind >= 226 && *wind <= 315))

或者像以前一样使用互斥锁

这很可能不是问题所在,但通过指针传递所有内容是什么?如果通过引用传递,则不需要所有指针语法。您对原子性的理解是错误的。看,原子弹上的每一个操作都是。。。原子的。多个不同的操作不是原子的。你认为原子变量是做什么的?@IInspectable谢谢!参考文献与指针与问题无关。我也很少看到比睡眠更丑陋的东西。睡眠很少是个好主意,在这里也不是个好主意。我并不是说以前的代码很好,但添加睡眠并不能真正改善它。@SergeyA我也为他的问题提供了答案,所以我认为指出outI没有问题,我认为我在main
std::thread t2(&wind\u thread,&wind)中是通过引用传递的我不需要在实际线程中取消引用它吗?而且,所有的睡眠都会使做同样的事情花费更长的时间。在我锁定线程之前,我已经试过了。@I3ck,你的第一点是不相关的(这里的引用并不比指针好,有些人甚至更喜欢指针),而你的第二点只是一个反模式。你的第三个建议只会起到部分作用。啊,这是有道理的。所以我仍然需要将它锁定在实际线程中。
int currentWind = wind->load();
if((currentWind >= 46 && currentWind <= 135) || (currentWind >= 226 && currentWind <= 315))