思想:
每个线程在对资源操作前都尝试先加锁,成功加锁才能操作,操作结束解锁
互斥锁实质上是操作系统提供的一把“建议锁”(又称“协同锁”),建议程序中有多线程访问共享资源的时候使用该机制。但,并没有强制限定。
主要应用函数:
pthread_mutex_init函数
pthread_mutex_destroy函数
pthread_mutex_lock函数 :阻塞发等待
pthread_mutex_trylock函数
pthread_mutex_unlock函数
pthread_mutex_t 类型,其本质是一个结构体
pthread_mutex_t mutex; 变量mutex只有两种取值1、0
1、pthread_mutex_init函数
-
函数原型:
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); -
参1:传出参数,调用时应传 &mutex
restrict关键字:只用于限制指针,告诉编译器,所有修改该指针指向内存中内容的操作,只能通过本指针完成。不能通过除本指针以外的其他变量或指针修改
-
参2:互斥量属性。是一个传入参数,通常传NULL,选用默认属性(线程间共享)
2、pthread_mutex_destroy函数
- 销毁一个互斥锁 int
- pthread_mutex_destroy(pthread_mutex_t *mutex)
3、pthread_mutex_lock函数
- 加锁。可理解为将mutex–(或-1)
- int pthread_mutex_lock(pthread_mutex_t *mutex);
4、pthread_mutex_unlock函数 - 解锁。可理解为将mutex ++(或+1)
- int pthread_mutex_unlock(pthread_mutex_t *mutex);
5、pthread_mutex_trylock函数 - 尝试加锁
- int pthread_mutex_trylock(pthread_mutex_t *mutex);
pthread_mutex_trylock函数和pthread_mutex_lock函数的区别:pthread_mutex_trylock不阻塞,pthread_mutex_lock阻塞
互斥量函数的应用:
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
void *tfn(void * arg)
{
srand(time(NULL));
while(1)
{
printf("hello ");
sleep(rand()% 3);
pritf("world\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);
pritf("WORLD\n");
sleep(rand() % 3);
}
return 0;
}
输出:
输出出现数据混乱:
主控线程和子线程共同操作标准输出这一个共享资源,
修改:加锁
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
pthread_mutex_t mutex;
void *tfn(void * arg)
{
srand(time(NULL));
while(1)
{
pthread_mutex_lock(&mutex);
printf("hello ");
sleep(rand()% 3);
printf("world\n");
pthread_mutex_unlock(&mutex);
sleep(rand() % 3);
}
return NULL;
}
int main()
{
pthread_t tid;
srand(time(NULL));
pthread_mutex_init(&mutex,NULL) //mutex == 1
pthread_create(&tid,NULL,tfn,NULL);
while(1)
{
pthread_mutex_lock(&mutex);
printf("HELLO");
sleep(rand()% 3);
pritf("WORLD\n");
pthread_mutex_unlock(&mutex);
sleep(rand() % 3);
}
pthread_mutex_destory(&mutex);
return 0;
}
输出:
结论:
- 在访问共享资源前加锁,访问结束后立即解锁。锁的“粒度”应越小越好。
- 互斥锁仅供一个线程使用