C/C++ volatile关键词探幽

我们先选定操作系统centOS。
选定GCC的版本

gcc version 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC)

先上我们的基础测试代码:
开两个线程,两个线程同时一起for循环:for i=1:n,对值sum进行累加,对sum值设置volatile和非volatile查看效果如何:

#include <semaphore.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>


//volatile int cnt=0; /* Counter */
int cnt=0;
sem_t mutex;        /* Semaphore that protects counter */


void *thread(void *vargp);  /* Thread routine prototype */



int main(int argc,char ** argv)
{
//    sem_unlink("mutex");
    sem_init(&mutex,0,1);   /* mutex=1 */
    int niters;
    pthread_t tid1,tid2;

    /* Check input argument */
    if(argc!=2)
    {
        printf("usage: %s <niters>\n",argv[0]);
        exit(0);
    }
    niters=atoi(argv[1]);

    /* Create threads and wait for them to finish */
    pthread_create(&tid1,NULL,thread,&niters);
    pthread_create(&tid2,NULL,thread,&niters);
    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);

    /* Check result */
    if(cnt!=(2*niters))
        printf("BOOM! cnt=%d\n",cnt);
    else
        printf("OK cnt=%d\n",cnt);
    exit(0);
}

/* Thread routine */
void *thread(void *vargp)
{
    volatile int i;
    volatile int niters=*((int *)vargp);
    for(i=0;i<niters;++i)
    {
        sem_wait(&mutex);
        cnt++;
        sem_post(&mutex);
    }
    return NULL;
}

我们尝试不同的组合方式:
1.volatile,累加10000的值
结果图如下:
这里写图片描述
看来volatile并不能保护我们的同步问题。

2.正常volatile,累加10000的值
结果图如下:
这里写图片描述
一样出现了多线程的累加错误问题。

3.volatile+信号量,累加10000的值
结果图如下:
这里写图片描述

加上了信号量之后,我们的结果正常了不少。

4.普通变量+信号量,累加10000的值
结果图如下:
这里写图片描述

即使我们采用了普通变量之后,我们的结果依旧正常。
看来volatile对我们的同步问题没有太大的帮助。
这时候发现我对volatile关键词并不具有很深的理解。下面放上知乎上对volatile的一些分析:
https://www.zhihu.com/question/31490495?sort=created

下面记录一个问题,我自己也没想明白的。
在我的主系统:macOS High Sierra 10.13.3版本上,利用pthread加了锁和volatile的结果仍不是正确的双倍结果:
这里写图片描述
得到答案的时候,我再把这个结果填上。

猜你喜欢

转载自blog.csdn.net/github_33873969/article/details/79736424