多线程编程 ------ 互斥量
1. 创建互斥量
pthreads 使用 pthread_mutex_t 类型的变量来表示互斥量,同时在使用互斥量进行同步前需要先对它进行初始化,可以用静态或动态的方式对互斥量进行初始化。
(1)静态初始化
对于静态分配的 pthread_mutex_t 变量来说,只要将 PTHREAD_MUTEX_INITIALIZER赋给变量就行了。
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
(2)动态初始化
对于动态分配或者不使用默认属性的互斥变量来说,需要调用 pthread_mutex_int()函数来执行初始化工作。 pthread_mutex_int()函数原型如下:
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
参数 mutex 是一个指向要初始化的互斥量的指针;参数 attr 传递 NULL 来初始化一个带有默认属性的互斥量,否则就要用类似于线程属性对象所使用的方法,先创建互斥量属性对象,再用该属性对象来创建互斥量。
函数成功返回 0,否则返回一个非 0 的错误码, 表 13.5 列出 pthread_mutex_init 出错的错误码。
静态初始化程序通常比调用 pthread_mutex_init 更有效,而且在任何线程开始执行之前,确保变量被初始化一次。
2. 销毁互斥量
销毁互斥量使用 pthread_mutex_destroy()函数,原型如下:
int pthread_mutex_destroy(pthread_mutex_t *mutex);
参数 mutex 指向要销毁的互斥量。以下代码销毁了 mylock 互斥量:
int error; pthread_mutex_t mylock; if (error = pthread_mutex_destroy(&mylock)) fprintf(stderr, "Failed to destroy mylock : %s\n", strerror(error));
加锁与解锁
加锁
pthreads 中有两个试图锁定互斥量的函数, pthread_mutex_lock()和 pthread_mutex_trylock()。pthread_mutex_lock()函数会一直阻塞到互斥量可用为止,而 pthread_mutex_trylock()则尝试加锁, 但通常会立即返回。函数原型如下:
int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_trylock(pthread_mutex_t *mutex);
解锁
pthread_mutex_unlock()函数用来释放指定的互斥量。函数原型如下:
int pthread_mutex_unlock(pthread_mutex_t *mutex);
死锁的避免
当多个线程需要相同的一些锁, 但是按照不同的顺序加锁, 死锁就很容易发生, 如果能确保所有的线程都是按照相同的顺序获得锁,那么死锁就不会发生。 例如,规定程序内有三个互斥锁的加锁顺序为 mutexA->mutexB->mutexC,则线程 t1、 t2、 t3 线程操作伪代码如下所示:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
2017-09-02 Qt 智能指针学习
2017-09-02 Qt中内存泄露和退出崩溃的问题 delete
2017-09-02 C++ --- 什么是多态