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

时间:2015-10-16 13:18:54

标签: multithreading vector is-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();
}

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

1 个答案:

答案 0 :(得分:1)

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

注意,当您向向量修改(插入)数据时,这还不足以执行那种例程。当您从向量中读取数据时,您还必须进行相同的舞蹈,因为修改需要独占访问,甚至读取也会违反此独占性。我在这里使用的非技术术语,“信令”,有一个技术对应物 - 它被称为关键部分。在这里,我们说您进入关键部分&#39;并且&#39;离开关键部分&#39;。

进入和离开关键部分的方法不止一种。这个问题就是所谓的mutexes,它们应该足以让你学习。请记住,还有其他方法,您将在适当的时候学习。