这是否会在多线程环境中不受干扰?

时间:2013-03-10 17:48:52

标签: c++ multithreading thread-safety deque thread-synchronization

std::deque<T> dq;
Thread_function(pointer to queue as argument)     // created 8 threads
{
     vertext_found = true;
     **v is initialized to NULL
     while ( i < dq->size())
     {
          EnterCriticalSection(&h);
          if( i < dq.size() ) {
              v = dq.at(i);      // accessing element of queue without popping
              i++;
              vertext_found = true;
          }
          LeaveCriticalSection(&h);
          if (vertext_found && (i < dq.size()) && v != NULL)
          {
              **operation on 'v'
              vertext_found = false;
          }
     }
}

这是否会成为数据竞争条件,尤其是在关键部分之外处理“ while(i&lt; dq-&gt; size())”时?我的方法是否正确?否则PLZ建议我。

1 个答案:

答案 0 :(得分:4)

  

这是否会在多线程环境中不受干扰?

在您的问题文本中,dq(与您函数中的所有其他变量一样)是 local 对象:

std::deque<T> dq;

如果情况确实如此,则问题的答案很简单:“是”。它是线程安全的,因为没有争用:每个线程都在本地对象上工作,并且由于没有共享,因此不会有任何数据争用。


现在假设您的代码旨在显示共享数据结构的使用,并且dq实际上是一个全局对象或某种方式可由多个线程同时访问(这是什么dq->size()函数调用似乎建议),然后答案是“它取决于”

如果所有线程同时只执行您正在显示的函数,并且dqconst 的引用或指针,那么您的函数不会包含对任何非const成员函数的任何调用,那么答案是“是,但是 你真的不需要任何在这种情况下,关键部分“。第17段.C ++ 11标准的6.5.9 / 3规定:

  

C ++标准库函数不应直接或间接修改线程可访问的对象(1.10)   除了当前线程之外,除非通过函数的非const直接或间接访问对象   参数,包括this

对第1.10段(尤其是1.10 / 21)的引用,定义了数据的种类,使上述段落的含义更加清晰:

  

如果程序在不同的线程中包含两个冲突的操作,则程序的执行包含数据竞争,   其中至少有一个不是原子的,也不会发生在另一个之前。任何此类数据竞赛都会产生   未定义的行为。 [...]

最后,第1.10 / 4段规定了两个行动何时发生冲突:

  

如果其中一个修改了内存位置(1.7)而另一个修改了另一个,则两个表达式评估会发生冲突   访问或修改相同的内存位置。

所有这些都是 const成员函数必须是线程安全的。您可能有兴趣观看this presentation by Herb Sutter

由于deque<T>::size()const成员函数,at()const成员函数(因为您是从引用或指向const的函数调用它})返回对const的引用,不需要同步来自多个线程的访问。


如果您的dq const 的引用或指针,则答案为“ “,因为at()是非const成员函数。此外,由于v是对元素的非const引用,因此您对“v”的操作可能不是const,因此会在元素上引入数据争用 dq而不是dq本身。

同样,如果你的帖子同时通过其他功能访问和修改dq,那么答案又是“否”,因为你没有保护对共享对象的所有访问。读操作与写操作冲突(见上文),您只是保护它们的部分。在这种情况下,您的关键部分应该跨越整个while周期。