c++ - 成员变量的更新值未反射(reflect)在 pthread 的线程路由函数中

标签 c++ pthreads

void MyThread::startThread()
{
    bStopThread = 0;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachedstate(&attr, PTHREAD_CREATE_JOINABLE);
    pthread_create(&threadID, &attr, threadFunc, this);
}

void MyThread::stopThread()
{
    bStopThread = 1;
}

void* MyThread::threadFunc(void* arg)
{
    MyThread* myThread = reinterpret_cast<MyThread*>(arg);

    while(myThread->bStopThread == 0)
    {

    }
}

在上面的代码示例中,当我调用 stopThread 函数时,我试图摆脱在线程例程函数中实现的 while 循环。但是当我测试这段代码时,我的 bool 变量在 stopThread 函数中发生了变化,但它没有反射(reflect)在线程例程函数中。谁可以帮我这个事。这里出了什么问题。我正在使用 NDK 在 android jni 中编译这段代码。我尝试为 bStopThread 变量提及 volatile 类型,但效果不佳。

最佳答案

可能有很多事情会导致这种行为。

  • 编译器可能会决定将这个变量放在一个寄存器中并读写这个寄存器。由于寄存器是线程专用的,因此任何其他线程都不会看到任何线程更改。
  • 编译器可以看到您没有更改 threadFunc() 中的变量,因此得出结论,只有 bStopThread 的初始状态很重要,没有理由进一步检查它并相应地优化您的代码。
  • CPU 可以将这个变量读写到它自己的缓存中,而不是主内存中,因此其他 CPU(其他线程)看不到它的变化。

通常 volatile 足以解决此类问题,但您编写它对您不起作用。

解决此问题的最简单方法是使用互斥锁来包装对 bStopThread 的访问。这将确保编译器和 CPU 都“获得消息”,即该变量供线程和 CPU 之间使用,并应进行相应处理。

另一个类似的选择是使用原子变量,例如std::atomic_bool.

如果您有兴趣了解更多信息,请在网上搜索“内存一致性”。

关于c++ - 成员变量的更新值未反射(reflect)在 pthread 的线程路由函数中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28320709/

相关文章:

c++ - 旋转矩阵特征库

c++ - 连接两个 time_t 值的日期和时间

c++ - 元组中的前向声明和交叉引用

c++ - Visual Studio 需要 "Redundant #include Guards"吗?

c - 如何在 C 中使用 pthreading

ruby - 使用 rvm 在没有 pthread 的情况下安装 ruby

c++ - QT QCharts添加删除系列

c++ - 即使设置为 PTHREAD_PROCESS_SHARED,Pthread 条件变量也不会发出信号

c++ - 这是POSIX兼容的实现,用于在多线程程序中处理诸如SIGFPE,SIGSEGV等信号吗?

c - pthreads并行化错误结果