STL是空的()线程安全吗?

cpp*_*dev 8 stl thread-safety

我有多个线程修改stl向量和stl列表.
如果容器是空的,我想避免必须锁定

以下代码是否是线程安全的?如果项目是列表或地图怎么办?

class A  
{  
    vector<int> items  
    void DoStuff()  
    {  
        if(!items.empty())  
        {  
            AquireLock();  
            DoStuffWithItems();  
            ReleaseLock();  
        }  
     }  
}  
Run Code Online (Sandbox Code Playgroud)

Kon*_*lph 6

这取决于你的期望.其他答案是正确的,一般来说,标准C++容器不是线程安全的,而且,特别是你的代码不会阻止另一个线程在你的调用empty和获取锁之间修改容器(但是这个问题)与线程安全无关vector::empty).

因此,要避免任何误解:您的代码不保证items在块内非空.

但是您的代码仍然有用,因为您只想避免冗余锁定创建.您的代码不提供保证,但可能会阻止不必要的锁创建.它在所有情况下都不起作用(其他线程仍然可以在检查和锁之间清空容器)但在某些情况下.如果您只是通过省略冗余锁来进行优化,那么您的代码就可以实现这一目标.

只需确保对容器的任何实际访问受到锁的保护.

顺便一句,上面严格来说是未定义的行为:理论上允许STL实现修改mutable调用内的成员empty.这将意味着,显然是无害的(因为只读)调用empty 可能实际上会导致冲突.不幸的是,您不能依赖于只读调用对STL容器是安全的假设.

但在实践中,我敢肯定,vector::empty不会修改任何成员.但已经因为list::empty我不太确定了.如果您真的需要保证,则要么锁定每个访问权限,要么不使用STL容器.