vector::empty() 函数在发布模式下无法正常工作


#include<iostream>
#include<vector>
#include<thread>
#include<string>
using namespace std;
vector<string> s;
void add()
{
    while(true)
    {
        getchar();
        s.push_back("added");
    }
}
void show()
{   
    while(true)
    {
        //cout<<"";
        while(!s.empty())
        {
            cout<<(*s.begin())<<endl;
            s.erase(s.begin());
        }
    }
}
int main()
{
    thread one(add);
    thread two(show);
    one.join();
    two.join();
}

在调试模式下没有这样的问题。在发布模式下,如果注释行未被注释,它将再次工作。但就像这样,有一个问题。有什么问题吗?

std::vector(与任何其他std::容器一样)通常不是线程安全的。这意味着通常不支持从多个线程并发修改访问同一向量。这意味着,虽然您可以同时从多个线程调用向量的非修改函数(例如,您可以毫无问题地调用begin()end()),但修改函数应该具有对向量对象的独占访问权。为了实现这种独占性,你需要使用线程同步原语来"表明"你想获得对vector的独占访问,执行你的修改,然后"表明"不再需要独占访问。

注意,当向vector对象修改(插入)数据时,这还不足以执行这种例程。当从vector中读取数据时,也必须做同样的事情,因为修改需要独占访问,甚至读取也会违反这种独占性。我在这里使用的非技术术语"信号"有一个技术对应——它被称为临界区。这里我们说你'进入临界区'和'离开临界区'。

进入和离开临界区不止一种方式。其中的要点就是所谓的mutexes,它们应该足够你学习了。只要记住还有其他的方法,在适当的时候你会学到。

最新更新