互斥量的使用
只有所有线程都遵循相同的数据访问规则的时候,锁机制才生效。
互斥量是一把锁,常见的操作有:
// 进行加锁,如果加锁失败,进程被阻塞int pthread_mutex_lock(pthread_mutex_t *mutex);// 尝试进行加锁。如果加锁成功,返回0;如果加锁失败,进程不会被阻塞,返回 EBUSYint pthread_mutex_trylock(pthread_mutex_t *mutex);// 进行解锁int pthread_mutex_unlock(pthread_mutex_t *mutex);
加锁失败的线程会陷入阻塞。获得锁的线程释放锁后,阻塞的所有线程都会被唤醒,然后尝试获取锁,获取失败的线程再度阻塞。
在使用互斥量之前,需要先进行初始化,使用完之后,要销毁互斥量。
// 初始化互斥量int pthread_mutex_init(phtread_mutex_t *mutex, const pthread_mutexattr_t *attr);// 销毁互斥量int pthread_mutex_destroy(pthread_mutex_t *mutex);
使用的例子:
#include <pthread.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>pthread_mutex_t g_mutex1; // 全局互斥量int g_num; // 全局变量void *thr_fn1(void *args){pthread_mutex_lock(&g_mutex1);g_num += 2;printf("[thread_1]g_num: %d\n", g_num);pthread_mutex_unlock(&g_mutex1);return (void *)0;}void *thr_fn2(void *args){pthread_mutex_lock(&g_mutex1);g_num += 3;printf("[thread_2]g_num: %d\n", g_num);pthread_mutex_unlock(&g_mutex1);return (void *)0;}int main(){void *rval; // 线程的返回值pthread_t tid1, tid2;// 初始化互斥量pthread_mutex_init(&g_mutex1, NULL);// 创建线程(void)pthread_create(&tid1, NULL, thr_fn1, NULL);(void)pthread_create(&tid2, NULL, thr_fn2, NULL);// 回收线程pthread_join(tid1, &rval);pthread_join(tid2, &rval);// 销毁互斥量pthread_mutex_destroy(&g_mutex1);exit(0);}
死锁
死锁情形1:一个线程对同一个互斥量加两次锁:
void *thr_fun1(void *args){pthread_mutex_lock(&g_mutex1);pthread_mutex_lock(&g_mutex2);// 陷入死锁}
死锁情形2:如果一个线程需要对多个互斥量进行加锁,那么需要确保多个线程之间加锁顺序一致。
有锁就必定有箱子,锁的作用是保护箱子中的内容的。在使用锁的时候,需要明确这把锁保护的是什么东西,定义好。
