多线程的坑--volatile

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程的坑--volatile相关的知识,希望对你有一定的参考价值。

多线程编程中 开优化选项时要谨慎否则容易掉坑里
先看下面的代码,开起两个线程,第二个线程把第一个线程的循环条件置成false 按逻辑来说这个应该能顺利结束的不过如果用
g++ -O3 -o multiThread multiThread.cpp -lpthread
编译的话TestThread1是退不出来的,只有 g_brun 加上 volatile关键字才能正常退出
因为在-O3优化选项下 执行TestThread1时g_brun会先读到寄存器中,编译器发现这个函数中g_brun没有任何改变所以不会再去内存中取值直接用寄存器中的备份,在TestThread2中改变了g_brun在内存中的值,对TestThread1中g_brun的寄存器备份没有任何影响。
加上volatile表示对该变量不优化每次都去内存中取值。

#include <pthread.h>
#include <iostream>
#include <unistd.h>
using namespace std;

//volatile bool g_brun = true;
bool g_brun = true;

void* TestThread1(void* arg)
{
    cout << "TestThread1 进入" << endl;

    long long ll = 0;
    while(g_brun)
        ll ++; 

    cout << "TestThread1 退出   ll:" << ll << endl;
}

void* TestThread2(void* arg)
{
    cout << "TestThread2 进入" << endl;
    g_brun = false;
    cout << "TestThread2 退出  设置 g_brun = false" << endl;
}

int main()
{
    pthread_t threadId1;
    pthread_create(&threadId1, NULL, TestThread1, NULL);
    usleep(1000000); // 保证TestThread1先执行
    pthread_t threadId2;
    pthread_create(&threadId2, NULL, TestThread2, NULL);

    pthread_join(threadId1,NULL);
    pthread_join(threadId2,NULL);

    return 0;
}

以上是关于多线程的坑--volatile的主要内容,如果未能解决你的问题,请参考以下文章

多线程的异步死循环和volatile关键字

多线程同步工具——volatile变量

为啥 volatile 在多线程 C 或 C++ 编程中没有用?

多线程之:正确使用 Volatile 变量

Java多线程的volatile底层实现原理

多线程 线程安全性的原理