首先我们说一个生活中的现象来类比线程同步,城市的每个十字路口都会设置有红绿灯,设置红绿等的作用就是为了让十字路口这个资源在一定时间内,只能被一个方向往来的车辆使用,以避免交通事故的发生,我们就可以理解为十字路口被同步了;这样我们就可以将这个例子类比到我们的线程同步,十字路口的红路灯就相当于我们的同步机制(互斥锁),东西、南北方向的行车就相当于两一条线程。
也就是说当两条线程需要访问同一块资源/临界资源时(十字路口),我们对这块临界资源加以限制(同步机制),让两条线程先后有序的来访问临界资源,这样就可以说这两条线程是同步的。
1、什么是互斥锁,有什么作用:
互斥锁是只能在线程之间使用的一种控制临界资源的访问机制。
如果一个线程要访问临界资源,则必须先加锁,用完之后解锁。这样在一个线程访问临界资源的过程中,其他线程如果加锁都会被阻塞,不能访问临界资源,直到这个线程解锁后,其他线才可以程竞争到锁,访问临界资源。(这样就做到了线程同步)
2、互斥锁的使用:
头文件:#include
定义锁:pthread_mutex_t //互斥锁的类型
初始化锁函数:int pthread_mutex_init(pthread_mutex_t* mutex,pthread_mutexattr_t* attr);
第一个参数是定义的互斥锁的地址,第二个参数是锁的属性,一般传NULL
加锁函数:int pthread_mutex_lock(pthread_mutex_t* mutex); //加锁失败就会阻塞
或 int pthread_mutex_trylock(pthread_mutex_t* mutex); //尝试加锁,成功返回0,失败则会返回错误码,不阻塞
解锁函数:int pthread_mutex_unlock(pthread_mutex_t* mutex);
销毁锁函数:int pthread_mutex_destroy(pthread_mutex_t* mutex);
3、例:创建两个子线程,让这两个线程交替给一个全局变量做++操作,每个线程加1万次,用线程同步的方式(加互斥锁),若不同步会怎样?
#include
#include
#include
#include
#define MAX 10000
int num ;
//定义锁
pthread_mutex_t mutex;
void* fun1()
{
int i = 0;
for(;i < MAX;i++)
{
pthread_mutex_lock(&mutex);//加锁
num++;
printf("A-->num=%d\n",num);
pthread_mutex_unlock(&mutex);//解锁
usleep(10);
}
}
void* fun2()
{
int i = 0;
for(;i < MAX;i++)
{
pthread_mutex_lock(&mutex);//加锁
num++;
printf("B-->num=%d\n",num);
pthread_mutex_unlock(&mutex);//解锁
usleep(10);
}
}
int main()
{
pthread_t pthid1,pthid2;
//初始化锁
pthread_mutex_init(&mutex,NULL);
pthread_create(&pthid1,NULL,fun1,NULL);
pthread_create(&pthid2,NULL,fun2,NULL);
pthread_join(pthid1,NULL);
pthread_join(pthid2,NULL);
printf("AB-->num=%d\n",num);
//销毁锁
pthread_mutex_destroy(&mutex);
return 0;
}
如果不采用同步的话最后可能数不到20000.