需求:使用10个线程,同时对一个值count进行加一操作,每个线程对count加100000次,最终使得count=1000000
第一版代码:不加锁
lock.c
#include<stdio.h>
#include<pthread.h>
#define THREAD_COUNT 10
void *thread_callback(void *arg){
int *pcount=(int*)arg;
int i=0;
while(i++ < 100000){
(*pcount)++;
usleep(1);//休眠一毫秒
}
}
int main(){
pthread_t threadid[THREAD_COUNT]={0};//定义多线程
int i=0;
int count=0;
for(i=0;i<THREAD_COUNT;i++){
pthread_create(&threadid[i],NULL,thread_callback,&count);
}
//每隔一秒打印一次count值
for(i=0;i<100;i++){
printf("count: %d\n",count);
sleep(1);//休眠一秒
}
return 0;
}
在Linux环境下编译执行:
编译: gcc -o lock lock.c -pthread
执行: ./lock
运行结果:
在不加锁的情况之下,使用多线程无法满足需求,即count值无法加到1000000.
从代码分析唯一能改变count值得代码是:count++,源代码中为:(*pcount)++
count++转化为汇编语言为:
正常情况(预期情况):每一个线程的count++都执行完再执行另外一个线程的count++
eax:寄存器
不正常情况(实际情况):当前线程中count++没完全执行完就跳转到另外一个线程执行
线程在执行代码的过程中被打断,这样所带来的的结果就是两个线程中执行两次count++,但count实际值只加了1,使得结果不能达到我们所预期的1000000值.
解决方法:使用互斥锁,或自旋锁,或原子操作。
第二版代码:这里使用互斥锁(mutex)
#include<stdio.h>
#include<pthread.h>
#define THREAD_COUNT 10
pthread_mutex_t mutex;//定义一个锁
void *thread_callback(void *arg){
int *pcount=(int*)arg;
int i=0;
while(i++ < 100000){
#if 0
(*pcount)++;
#else
pthread_mutex_lock(&mutex);//上锁
(*pcount)++;
pthread_mutex_unlock(&mutex);//解锁
#endif
usleep(1);//休眠一毫秒
}
}
int main(){
pthread_t threadid[THREAD_COUNT]={0};//定义多线程
pthread_mutex_init(&mutex,NULL);//初始化锁,NULL为系统默认
int i=0;
int count=0;
for(i=0;i<THREAD_COUNT;i++){
pthread_create(&threadid[i],NULL,thread_callback,&count);
}
for(i=0;i<100;i++){
printf("count: %d\n",count);
sleep(1);//休眠一秒
}
return 0;
}
运行结果: