以下是
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
方法。const Block *& pfb从每个线程的worker方法传递如下:
int maxIndex;
const Block *pfb = null;
pStoredBlcks->GetNthBlockA(blockBreakIndex, pfb, maxIndex);
我担心const
可能会在两个工人的身体之间造成意想不到的影响。我98%的错误来自上面的代码但是,由于多线程的特殊性,我无法更加确定。
我接近我的问题限制24小时,还有一件事,如果它可能会有所帮助。 static_cast<>
线程安全吗? (傻?是的,但我写了C多年)我问因为:
const Block *GetNthblckB(int n) const {
return static_cast<const Block*>(Blocks.GetAt(n));//Returns `Object`* without cast.
}
3am_ _ _ 谢谢你们的鼓励。我刚用CritSecMonitor包围了那个调用,我仍然有副作用。如果没有阅读valgrind手册,我最好抓住一些zz的。
答案 0 :(得分:3)
线程安全的第一个事实:如果两个函数f()
和g()
都是线程安全的,那么以下函数不一定是线程安全的:
// h might not be thread-safe!
void h()
{
f(); // f is thread-safe
g(); // g is thread-safe
}
所以你必须根据函数GetNthBlckB
,GetNthInt
等的内容证明线程安全。我不知道这些方法做了什么,所以我不知道是否它们是否是线程安全的(const
与它无关)。 看起来就好像对我来说不是线程安全的。
答案 1 :(得分:0)
Blocks.GetAt()是一个不可变的方法(不会改变任何内部状态)?例如,它可能不是,如果它使用缓存从数据库或文件中读取。
此外,您的问题的答案还取决于数据的初始化时间。
是否在生成任何线程之前?
另外,我建议您定期在项目中使用valgrind的drd和helgrind,以帮助您找到当前的错误,并防止将来的线程错误进入您的项目。
最后一个建议是,当对线程安全性有疑问时,请输入您自己的互斥锁。 如果您可以通过互斥锁显示它运行正常,那么您可以隔离错误/错误假设/关键部分。
答案 2 :(得分:0)
在回答我的问题时,我以为其他人已经说过这个:
不要假设任何库函数都是线程安全的,除非它说是。
我98%的猜测是错误的,并且线程不安全的方法在一个库实例方法的其他地方使用完全独立的对象但是从两个线程调用。那里肯定有一个静态变量,因为调用堆栈会崩溃(很少)看起来在库代码中很深。