我们先选定操作系统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的结果仍不是正确的双倍结果:
得到答案的时候,我再把这个结果填上。