以下C ++代码线程是否安全?

时间:2012-01-31 02:49:50

标签: 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.GetNthInt(n + 1) - 1;
    return formattingPivots.GetNthInt(n);
}

线程安全考虑:

  1. formattingPivots.GetNthBlckB(n)formattingPivots.GetNthInt(n + 1)formattingPivots.GetNthInt(n)formattingPivots.GetCount()都是const方法。
  2. 我从2个线程调用GetNthBlock(),当thread1调用并返回一个常用块时,我注意到thread2中有副作用。
  3. const Block *& pfb从每个线程的worker方法传递如下:

    int maxIndex;
    const Block *pfb = null;
    pStoredBlcks->GetNthBlockA(blockBreakIndex, pfb, maxIndex);
    
  4. 我担心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的。

3 个答案:

答案 0 :(得分:3)

线程安全的第一个事实:如果两个函数f()g()都是线程安全的,那么以下函数不一定是线程安全的:

// h might not be thread-safe!
void h()
{
    f(); // f is thread-safe
    g(); // g is thread-safe
}

所以你必须根据函数GetNthBlckBGetNthInt等的内容证明线程安全。我不知道这些方法做了什么,所以我不知道是否它们是否是线程安全的(const与它无关)。 看起来就好像对我来说不是线程安全的。

答案 1 :(得分:0)

Blocks.GetAt()是一个不可变的方法(不会改变任何内部状态)?例如,它可能不是,如果它使用缓存从数据库或文件中读取。

此外,您的问题的答案还取决于数据的初始化时间。

是否在生成任何线程之前?

另外,我建议您定期在项目中使用valgrind的drdhelgrind,以帮助您找到当前的错误,并防止将来的线程错误进入您的项目。

上次推荐

最后一个建议是,当对线程安全性有疑问时,请输入您自己的互斥锁。 如果您可以通过互斥锁显示它运行正常,那么您可以隔离错误/错误假设/关键部分。

答案 2 :(得分:0)

在回答我的问题时,我以为其他人已经说过这个:

不要假设任何库函数都是线程安全的,除非它说是。

我98%的猜测是错误的,并且线程不安全的方法在一个库实例方法的其他地方使用完全独立的对象但是从两个线程调用。那里肯定有一个静态变量,因为调用堆栈会崩溃(很少)看起来在库代码中很深。