2012-10-18 17 views
0

考虑多线程程序下面的代码:它是否仍然线程安全,如果我先做()然后pop_front()?

QString target = remaining.first(); // remaining is a QVector<QString> class 
    remaining.pop_front(); 

难道是安全的?看起来像多个线程可能同时使用相同的“目标”。或者什么是安全的方式来检索+删除第一个值?

+0

你有周围的代码互斥? –

+0

@JonathanWakely nope – daisy

回答

2

没有一个互斥体来保护那个代码,不,它一点也不安全。

我不知道详细QVector,但我相信这是两个线程都OK事:

QString target = remaining.first(); 

这只是拷贝向量的元素,所以每个线程都有自己的QString对象调用target他们是独立的对象(在幕后,他们使用implicit sharing所以不是独立的,但你应该能够treat them as independent

但此行修改QVector

remaining.pop_front(); 

这意味着两个线程修改相同的对象,而无需任何的同步。如果第二个线程调用pop_front()时,第一个线程仍然通过调用remaining.first()访问该向量,则存在数据竞争,具有未定义的行为。

同样,如果两个线程调用pop_front()同时他们都将尝试删除第一个元素,会发生什么情况存在完全不可预测的。您可能会删除一个或两个元素,或者不删除,或立即崩溃整个程序。作为另一种可能性,考虑如果矢量只有一个元素会发生什么。这两个线程检查它不是空的,复制first()元素,然后调用pop_front(),它试图删除两个元素时,只有一个。你的程序坏了。

的安全的方式来做到这一点是保护代码一个互斥体,其中mutex是一些全球性或以其他方式共享变量是可见的两个线程:

QString target; 
{ 
    QMutexLocker locker(&mutex); 
    if (!remaining.empty()) 
    { 
    target = remaining.first(); 
    remaining.pop_front(); 
    } 
} 
相关问题