##互斥量mutex
前文提及linux arg,系统中假如存在资源共享,线程间存在竞争,而且没有合理的同步机制的话,会出现数据混乱的现象。为了实现同步机制,Linux中提供了多种方法,其中一种方法为互斥锁mutex(亦称之为互斥量)。
互斥量的具体实现方法为:每位线程在对共享资源操作前都尝试先加锁,成功加锁后才可以对共享资源进行读写操作,操作结束后解锁。
互斥量不是为了清除竞争,实际上,资源还是共享的,线程间也还是竞争的,只不过通过这些“锁”机制就将共享资源的访问弄成互斥操作,也就是说一个线程操作这个资源时,其它线程难以操作它linux虚拟主机,因而去除与时间有关的错误。
从互斥量的实现机制我们可以看出,同一时刻,只能有一个线程持有该锁。假如有同时有多个线程持有该锁,那就没有实际意义了。
然而,这些锁机制不是强制的,互斥锁实质上是操作系统提供的一把“建议锁”(又称“协同锁”),建议程序中有多线程访问共享资源的时侯使用该机制。
为此,虽然有了mutex,其它线程倘若不依照这些锁机制来访问共享数据的话,仍然会导致数据混乱。所以为了防止这些情况,所有访问该共享资源的线程必须采用相同的锁机制。
主要应用函数:
pthread_mutex_init函数pthread_mutex_destroy函数pthread_mutex_lock函数pthread_mutex_trylock函数pthread_mutex_unlock函数
以上5个函数的返回值都是:成功返回0,失败返回错误号。
在Linux环境下,类型pthread_mutex_t其本质是一个结构体。并且为了简化理解,应用时可忽视其实现细节,简单当作整数看待。mutex通常以下边形式定义:
pthread_mutex_tmutex;
变量mutex只有两种取值1、0。
##pthread_mutex_init函数
函数原型:
intpthread_mutex_init(pthread_mutex_trestrictmutex,constpthread_mutexattr_trestrictattr);
函数作用:
初始化一个互斥锁(互斥量)mutex,年率可视为1;
参数介绍:
mutex:传出参数,调用时应传&mutex给该函数;
这儿有个关键字比较特殊:restrict。它的作用只用于限制表针,告诉编译器,所有更改该表针指向显存中内容的操作,只能通过本表针完成。不能通过除本表针以外的其他变量或表针更改。例如说,再定义个pthread_mutex_t的表针,将其形参为mutex的值,想要用它来更改mutex所指向的显存,这是不容许的。
attr:互斥量属性。是一个传入参数,一般传NULL,表示使用默认属性(即:线程间共享)。
对于互斥量mutex的初始化有两种形式:
1.静态初始化:
假如互斥锁mutex是静态分配的,即:定义为全局变量红旗linux下载,或加了static关键字修饰,可以直接使用宏进行初始化。e.g.pthead_mutex_tmuetx=PTHREAD_MUTEX_INITIALIZER;
2.动态初始化:
假如互斥锁mutex定义为局部变量,则应采用动态初始化。e.g.pthread_mutex_init(&mutex,NULL)
##pthread_mutex_destroy函数
函数原型:
intpthread_mutex_destroy(pthread_mutex_t*mutex);
函数作用:
销毁一个互斥锁
pthread_mutex_lock函数
函数原型:
intpthread_mutex_lock(pthread_mutex_t*mutex);
函数作用:
对共享资源进行加锁。可理解为将mutex--(或-1);假如加锁不成功,则该线程将阻塞,直至持有该互斥量的其他线程解锁为止。注意:在访问共享资源前加锁,访问结束后立刻解锁。锁的“粒度”应越小越好。
pthread_mutex_unlock函数
函数原型:
intpthread_mutex_unlock(pthread_mutex_t*mutex);
函数作用:
对共享资源解锁。可理解为将mutex++(或+1);在解锁的同时,会将阻塞在该锁上的所有线程全部唤起,至于那个线程先被唤起,取决于优先级、调度。默认情况下:先阻塞的线程会先被唤起。
##pthread_mutex_trylock函数
函数原型:
intpthread_mutex_trylock(pthread_mutex_t*mutex);
函数作用:
对共享资源尝试加锁。它与pthread_mutex_lock函数的区别是,使用lock函数对共享资源进行加锁时linux arg,假若加锁不成功,则线程就阻塞;而倘若使用trylock,则加锁不成功时不会阻塞当前线程,而是立刻返回一个值来描述互斥锁的状况。
死锁:
线程企图对同一个互斥量A加锁两次。线程1拥有A锁,恳请获得B锁;线程2拥有B锁,恳请获得A锁
#include
#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("world!n");
pthread_mutex_unlock(&mutex);
sleep(rand() % 3);
}
return NULL;
}
int main()
{
pthread_t tid;
int n = 5;
srand(time(NULL));
pthread_mutex_init(&mutex, NULL);
pthread_create(&tid, NULL, tfn, NULL);
while(n--) {
pthread_mutex_lock(&mutex);
printf("HELLO ");
sleep(rand() % 3);
printf("WORLD!n");
pthread_mutex_unlock(&mutex);
sleep(rand() % 3);
}
pthread_cancel(tid);
pthread_join(tid, NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
>2020精选阿里/腾讯等一线大厂笔试、简历、进阶、电子书「**良许Linux**」后台回复「**资料**」免费获取
####看完的都是真爱,点个赞再走呗?您的「三连」就是良许持续创作的最大动力!
1.关注**原创**「**良许Linux**」,第一时间获取最新Linux干货!
2.后台回复【资料】【面试】【简历】获取精选一线大厂笔试、自我提高、简历等资料。
3.关注我的博客:[]()