#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
,它们应该足够你学习了。只要记住还有其他的方法,在适当的时候你会学到。