C++ 是以下C++;代码线程安全?
以下是C++ 是以下C++;代码线程安全?,c++,multithreading,parameters,C++,Multithreading,Parameters,以下是 int BlkArray::GetNthBlockA(unsigned int n, const Block *&pfb, int &maxIndex) const { if (n + 1 >= (unsigned int)formattingPivots.GetCount()) return -1; pfb = formattingPivots.GetNthBlckB(n); maxIndex = formattingPivots.GetN
int BlkArray::GetNthBlockA(unsigned int n, const Block *&pfb, int &maxIndex) const {
if (n + 1 >= (unsigned int)formattingPivots.GetCount()) return -1;
pfb = formattingPivots.GetNthBlckB(n);
maxIndex = formattingPivots.GetNthInt(n + 1) - 1;
return formattingPivots.GetNthInt(n);
}
线程安全考虑:
formattingPivots.GetNthBlckB(n)
,formattingPivots.GetNthInt(n+1)
,formattingPivots.GetNthInt(n)
和formattingPivots.GetCount()
都是const
方法int maxIndex;
const Block *pfb = null;
pStoredBlcks->GetNthBlockA(blockBreakIndex, pfb, maxIndex);
const
可能会对两个工人身体之间的持久性造成意外影响。我知道98%的bug来自上面的代码,但是,由于多线程的特殊性,我不能得到更多的肯定
我已经接近24小时的提问上限了,还有一件事,如果有帮助的话。static\u cast
线程安全吗?(愚蠢?是的,但我写C已经很多年了)我问是因为:
const Block *GetNthblckB(int n) const {
return static_cast<const Block*>(Blocks.GetAt(n));//Returns `Object`* without cast.
}
const块*GetNthblckB(int n)const{
返回static_cast(Blocks.GetAt(n));//返回没有强制转换的`Object`*。
}
凌晨3点___
谢谢你们的鼓励。我刚刚用CritSecMonitor包围了那个电话,我仍然有副作用。除了阅读valgrind手册之外,我最好能理解一些zz。是Blocks.GetAt()一个不可变的方法(不会改变任何内部状态)?例如,如果它使用缓存从数据库或文件中读取,则可能不是
此外,问题的答案还取决于数据的初始化时间
是在产生任何线程之前吗
此外,我建议您在项目中定期使用valgrind和,以帮助您发现当前的bug,并防止将来的线程bug进入项目
最后建议
最后一个建议是,当对线程安全性有疑问时,加入您自己的互斥锁。
如果您可以显示它使用互斥锁运行良好,那么您可以隔离错误/错误假设/关键部分。线程安全的一个事实:如果两个函数f()
和g()
都是线程安全的,那么以下函数不一定是线程安全的:
// h might not be thread-safe!
void h()
{
f(); // f is thread-safe
g(); // g is thread-safe
}
因此,您必须根据函数
GetNthBlckB
,GetNthInt
等的内容来证明线程安全性。我不知道这些方法做什么,所以我不知道它们是否线程安全(const
与此无关)。在我看来,它不是线程安全的。在回答我的问题时,我以为其他人已经说过:
不要假设任何库函数都是线程安全的,除非它说它是线程安全的
我98%的猜测是错误的,线程不安全方法位于库实例方法的其他位置,使用完全分离的对象,但从两个线程调用。那里一定有一个静态变量,因为它会崩溃的调用堆栈(很少)看起来在库代码的深处。
static\u cast
在运行时在指针上使用时不会做任何事情,所以您可以使用它而不用担心弄乱线程。您还可以使用关键部分来查看问题是否来自同时运行该代码的多个线程。@SethCarnegie,除非他放弃了该方法的实现正在更改状态的事实-在这种情况下,可能需要一个互斥锁needed@SethCarnegie,我正在使用Monitor
s(CS)。但是我已经深入钻研了非关键部分来针对这个bug。我不介意它们同时运行代码,即使它们共享pStoredBlcks
(它们共享),它们在那里应该是安全的。在我释放线程之前,初始化就已经完成了。GetAt()是一个不可变的方法。那么我建议您调出valgrind的drd(在答案中添加了链接)。如果我不知道用于数组访问的库方法是否是线程安全的,这有什么用呢?我想我必须为自己证明这一点。你应该能够通过使用互斥锁和线程检查器的组合来说服自己。我有点希望避免将CSMonitor深入到线程安全的非关键部分。它们只做调用库方法的工作。我不知道这些库方法是否是线程安全的,它们声称模拟数组<代码>Osp::Base::Collection::ArrayListintgetnthint(intn)const{intreti;GetAt(n,reti);return reti;}
@John:library文档中出现的“线程安全”的定义因库而异。库是否表示允许对同一对象进行并发访问?许多库使用“线程安全”的定义,即“只要两个线程不使用同一对象,就安全”。其他库允许多个并发读取,但需要排除更改。