考虑多线程程序下面的代码:它是否仍然线程安全,如果我先做()然后pop_front()?
QString target = remaining.first(); // remaining is a QVector<QString> class
remaining.pop_front();
难道是安全的?看起来像多个线程可能同时使用相同的“目标”。或者什么是安全的方式来检索+删除第一个值?
考虑多线程程序下面的代码:它是否仍然线程安全,如果我先做()然后pop_front()?
QString target = remaining.first(); // remaining is a QVector<QString> class
remaining.pop_front();
难道是安全的?看起来像多个线程可能同时使用相同的“目标”。或者什么是安全的方式来检索+删除第一个值?
没有一个互斥体来保护那个代码,不,它一点也不安全。
我不知道详细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();
}
}
你有周围的代码互斥? –
@JonathanWakely nope – daisy