成员变量的更新值未反映在 pthread 的线程路由函数中

updated value of member variable is not reflacted within thread routin function in pthread

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 循环。但是当我测试这段代码时,我的布尔变量在 stopThread 函数中发生了变化,但它没有反映在线程例程函数中。谁可以帮我这个事。这里出了什么问题。我正在使用 NDK 在 android jni 中编译这段代码。我尝试为 bStopThread 变量提及 volatile 类型,但它的效果不佳。

可能有很多原因会导致此行为。

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

通常 volatile 足以解决此类问题,但您编写它并不适合您。

解决此问题的最简单方法是使用互斥体包装对 bStopThread 的访问。这将确保编译器和 CPU "get the message" 该变量供线程和 CPU 之间使用,并应相应地对待。

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

如果您有兴趣了解更多信息,请在网上搜索 "Memory Coherency"。