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建议我。
答案 0 :(得分:4)
这是否会在多线程环境中不受干扰?
在您的问题文本中,dq
(与您函数中的所有其他变量一样)是 local 对象:
std::deque<T> dq;
如果情况确实如此,则问题的答案很简单:“是”。它是线程安全的,因为没有争用:每个线程都在本地对象上工作,并且由于没有共享,因此不会有任何数据争用。
现在假设您的代码旨在显示共享数据结构的使用,并且dq
实际上是一个全局对象或某种方式可由多个线程同时访问(这是什么dq->size()
函数调用似乎建议),然后答案是“它取决于”。
如果所有线程同时只执行您正在显示的函数,并且dq
是const
的引用或指针,那么您的函数不会包含对任何非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
周期。