0

考虑多线程程序中的以下代码:

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

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

4

1 回答 1

2

如果没有保护该代码的互斥锁,不,它根本不安全。

我不知道QVector详细信息,但我相信两个线程都可以这样做:

QString target = remaining.first();

这只是复制向量的一个元素,因此每个线程都有自己的QString对象被调用target并且它们是独立的对象(在幕后它们使用隐式共享所以不是独立的,但你应该能够将它们视为独立的

但是这一行修改了QVector

remaining.pop_front();

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

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

安全的方法是使用互斥锁保护代码,其中mutex一些全局变量或其他共享变量对两个线程都是可见的:

QString target;
{
  QMutexLocker locker(&mutex);
  if (!remaining.empty())
  {
    target = remaining.first();
    remaining.pop_front();
  }
}
于 2012-10-18T16:37:09.847 回答