2015-10-16 51 views
0
#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(); 
} 

在调试模式下,不存在这样的问题。在发布模式下,如果注释行未注释,则它会再次运行。但就像这样,就有一个问题。问题是什么?在发布模式下,vector :: empty()函数无法正常工作

+2

您的代码被破坏,因为您有两个线程操纵矢量而没有同步。使用互斥锁。 –

+0

但它适用于{cout <<“”;} – sunofkyuss

+1

它看起来可行,但那不可靠。严重的是,获得关于多线程的教程,它会解释一些事情。 –

回答

1

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

注意,当您修改(插入)数据到矢量时,这不足以执行那种例程。当您从矢量中读取数据时,您也必须执行相同的跳舞,因为修改需要独占访问权限,甚至读取也会违反这种排他性。我在这里使用的非技术术语“信号”,有一个技术对应物 - 它被称为临界区。在这里,我们说你'进入关键部分'和'离开关键部分'。

有多种方式进入并离开关键部分。这些瑕疵是所谓的mutexes,它们应该足以让你学习。请记住,还有其他方法,您将在适当的时候学习。