如图所示:
但是应该注意:同一个时刻,只能有一个线程持有该锁。
当A线程对某个全局变量加锁访问,B在访问前尝试加锁,拿不到锁,B阻塞。C线程不去加锁,而直接访问该全局变量,依然能够访问,但会出现数据混乱。
所以,互斥锁实质上是是操作系统提供的一把“建议锁”(又称“协同所”),建议程序中有多线程访问共享资源的时候使用该机制,但是,并没有强制限定。
分析:
1. 函数原型:
功能:初始化一个互斥锁(互斥量); 初值可看做1
#include
pthread_mutex_init(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
返回值:若成功,返回0,否则,返回错误编号
参数1:传出参数,调用时应传&mutex
参数2:互斥属性。是一个传入参数,通常传NULL,选用默认属性(线程间共享).
2. 函数原型:
功能:销毁一个互斥锁
#include
pthread_mutex_destroy(pthread_mutex_t *mutex);
返回值:若成功,返回0,否则,返回错误编号
3. 函数原型:
功能:加锁。可理解为将mutex--(或-1)
#include
pthread_mutex_lock(pthread_mutex_t *mutex);
返回值:若成功,返回0,否则,返回错误编号
分析:
4. 函数原型:
功能:解锁。可理解为将mtex++(或+1)
#include
pthread_mutex_unlock(pthread_mutex_t *mutex);
返回值:若成功,返回0,否则,返回错误编号
注意:
5. 函数原型:
功能:尝试加锁, 失败返回, 不阻塞
#include
pthread_mutex_trylock(pthread_mutex_t *mutex);
返回值:若成功,返回0,否则,返回错误编号
分析:
1. 测试代码:
#include
#include
#include
#include
#include
void *tfn(void *arg)
{
srand(time(NULL));
while(1) {
printf("hello ");
sleep(rand() % 3); //模拟长时间操作共享资源,导致cpu易主,产生与时间有关的错误
printf("word\n");
sleep(rand() % 3);
}
return NULL;
}
int main()
{
pthread_t tid;
srand(time(NULL));
pthread_create(&tid, NULL, tfn, NULL);
while(1) {
printf("HELLO ");
sleep(rand() % 3);
printf("WORLD\n");
sleep(rand() % 3);
}
return 0;
}
运行结果:
2. 测试代码:
#include
#include
#include
pthread_mutex_t mutex;
void *tfn(void *arg)
{
srand(time(NULL));
while(1) {
pthread_mutex_lock(&mutex);
printf("hello ");
sleep(rand() % 3); //模拟长时间共享资源,导致cpu易主。产生于时间有关的错误
printf("word\n");
pthread_mutex_unlock(&mutex);
sleep(rand() % 3);
}
return NULL;
}
int main()
{
pthread_t tid;
srand(time(NULL));
pthread_mutex_init(&mutex, NULL);
pthread_create(&tid, NULL, tfn, NULL); //mutex == 1
while(1) {
pthread_mutex_lock(&mutex);
printf("HELLO ");
sleep(rand() % 3);
printf("WORLD\n");
pthread_mutex_unlock(&mutex);
sleep(rand() % 3);
}
pthread_mutex_destroy(&mutex);
return 0;
}
输出结果:
3. 测试代码:
#include
#include
#include
pthread_mutex_t mutex;
void *tfn(void *arg)
{
srand(time(NULL));
while(1) {
pthread_mutex_lock(&mutex);
printf("hello ");
sleep(rand() % 3); //模拟长时间共享资源,导致cpu易 主。产生于时间有关的错误
printf("word\n");
sleep(rand() % 3);
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main()
{
pthread_t tid;
srand(time(NULL));
pthread_mutex_init(&mutex, NULL);
pthread_create(&tid, NULL, tfn, NULL); //mutex == 1
while(1) {
pthread_mutex_lock(&mutex);
printf("HELLO ");
sleep(rand() % 3);
printf("WORLD\n");
sleep(rand() % 3);
pthread_mutex_unlock(&mutex);
}
pthread_mutex_destroy(&mutex);
return 0;
}
输出结果:
lock与unlock:
例如:T1 T2 T3 T4 使用一把mutex锁,T1加锁成功,其他线程均阻塞,直至T1解锁,T1解锁后,T2 T3 T4均被唤醒,并自动再次尝试加锁。
可假想mutex锁init成功初值为1。lock功能是将mutex--。unlock将mutex++。
lock与trylock:
注意:在访问共享资源前加锁,访问结束后立即解锁。锁的“粒度”越小越好。