pthread mutex 属性

本文详细介绍了pthread mutex的四种属性:NORMAL、ERRORCHECK、RECURSIVE和DEFAULT。NORMAL类型不检测死锁,可能导致程序卡住;ERRORCHECK提供错误检查,重复操作会返回错误;RECURSIVE允许同一线程多次加锁,但需要对应次数解锁;DEFAULT属性可能导致未定义行为。建议避免使用NORMAL和DEFAULT,而是选择ERRORCHECK和RECURSIVE以确保更好的错误处理和防止死锁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mutex互斥锁有四种属性,分别是NORMAL, ERRORCHECK, RECURSIVE, DEFAULT,通过pthread_mutexattr_settype 对互斥锁进行属性设置。

PTHREAD_MUTEX_NORMAL

This type of mutex does not detect deadlock. A thread attempting to relock this mutex without first unlocking it shall deadlock. Attempting to unlock a mutex locked by a different thread results in undefined behavior. Attempting to unlock an unlocked mutex results in undefined behavior.

PTHREAD_MUTEX_ERRORCHECK

This type of mutex provides error checking. A thread attempting to relock this mutex without first unlocking it shall return with an error. A thread attempting to unlock a mutex which another thread has locked shall return with an error. A thread attempting to unlock an unlocked mutex shall return with an error.

PTHREAD_MUTEX_RECURSIVE

A thread attempting to relock this mutex without first unlocking it shall succeed in locking the mutex. The relocking deadlock which can occur with mutexes of type PTHREAD_MUTEX_NORMAL cannot occur with this type of mutex. Multiple locks of this mutex shall require the same number of unlocks to release the mutex before another thread can acquire the mutex. A thread attempting to unlock a mutex which another thread has locked shall return with an error. A thread attempting to unlock an unlocked mutex shall return with an error.

PTHREAD_MUTEX_DEFAULT

Attempting to recursively lock a mutex of this type results in undefined behavior. Attempting to unlock a mutex of this type which was not locked by the calling thread results in undefined behavior. Attempting to unlock a mutex of this type which is not locked results in undefined behavior. An implementation may map this mutex to one of the other mutex types.

由于 DEFAULT 与 NORMAL 属性有太多的未定义行为,所以应该尽可能的避免使用。NORMAL会导致死锁,并不会反回错误代码,因而程序会卡住。互斥锁默认属性为NORMAL。

ERRORCHECK 重复加锁,重复解锁都会返回错误代码,不会导致死锁。
RECURSIVE 允许同一线程进行N次加锁,但必须进行N次解锁才能释放这把锁。A线程Lock后,B线程再次LOCK的时候,发生死锁。(试验环境 Linux ubuntu 3.19.0-25-generic #26~14.04.1-Ubuntu)

综上,避免使用NORMAL与DEFAULT属性,显示的设置ERRORCHECK与RECURSIVE属性。

<think>好的,我现在需要帮助用户了解pthread_mutex的使用方法,包括示例和语法说明。首先,我得回忆一下pthread_mutex的基本概念,它是POSIX线程库中用于互斥锁的操作,用来保护多线程环境下的共享资源,防止竞争条件。 接下来,用户需要的是使用方法和示例,所以我应该先解释相关的函数,比如pthread_mutex_init、pthread_mutex_lock、pthread_mutex_unlock和pthread_mutex_destroy。需要确保每个函数的参数和返回值都说明清楚,特别是像pthread_mutex_init中的attr参数,可能需要提到默认属性或者不同类型的互斥锁,比如PTHREAD_MUTEX_DEFAULT等,但用户可能不需要太深入,所以简要提及即可。 然后,示例代码部分很重要。用户可能希望看到一个实际的多线程例子,比如多个线程操作共享变量,比如卖票系统。需要确保代码中正确使用互斥锁来保护临界区。同时,要注释清楚每个步骤,让用户明白哪里加锁,哪里解锁。另外,还要注意编译时需要链接pthread库,所以在编译命令中加入-lpthread是必要的,这点需要提醒用户,避免编译错误。 另外,用户提供的引用中有提到线程间的互斥操作示例和编译命令,这些可以作为参考。例如引用[2]中的卖票场景,引用[4]中的编译命令。需要确保示例代码符合这些引用内容,正确使用互斥锁,并且在编译时添加-lpthread。 还要注意用户提到的系统级指令,比如行内数学表达式用$...$,但在这个问题中可能用不上,但如果有变量或代码,需要正确格式化。例如代码块用反引号包裹,并注明语言类型。 可能的问题点:如何初始化互斥锁?动态初始化和静态初始化的区别是什么?需要解释PTHREAD_MUTEX_INITIALIZER和pthread_mutex_init的使用场景。另外,互斥锁的类型属性,比如普通锁、递归锁等,但用户的问题可能不需要深入到这里,除非示例中用到,所以可能不需要详细展开,但可以简要提及。 在写示例的时候,要确保锁的正确使用,避免死锁情况,比如在每次lock之后都要有对应的unlock,即使在错误处理情况下也需要释放锁吗?不过示例可能不需要处理太复杂的情况,保持简单明了即可。 总结步骤: 1. 引入pthread_mutex的基本函数,解释每个函数的作用和参数。 2. 提供一个具体的代码示例,比如多线程卖票,展示如何用互斥锁保护共享变量。 3. 指出编译时需要链接pthread库,给出编译命令。 4. 注意事项部分,提醒用户正确使用锁,避免死锁,以及初始化和销毁的重要性。 5. 根据用户提供的引用,特别是引用[2]和[4],确保示例符合这些引用中的内容,并在回答末尾添加引用标识。 6. 最后生成相关问题,帮助用户进一步学习,比如错误处理、属性设置、与其他同步机制对比等。 现在需要检查是否有遗漏的函数或者常见错误,比如忘记销毁互斥锁,或者没有处理线程的创建和连接。在示例代码中,确保线程函数正确使用锁,共享变量被保护。此外,互斥锁的初始化是否正确,静态初始化是否适用,或者是否需要动态初始化。在示例中,使用pthread_mutex_init进行动态初始化,或者在全局变量中使用PTHREAD_MUTEX_INITIALIZER。根据用户提供的引用,可能更倾向于动态初始化,或者两种方式都提及。 最后,确保回答结构清晰,分点说明,代码示例正确,并且相关问题能够引导用户深入学习。</think>### pthread_mutex 使用详解 `pthread_mutex` 是 POSIX 线程库中用于实现互斥锁的核心工具,用于保护多线程环境下的共享资源,防止数据竞争。以下是其核心函数与使用示例: --- #### 核心函数说明 1. **初始化互斥锁** - **动态初始化**: ```c int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); ``` 参数说明: - `mutex`:互斥锁对象指针 - `attr`:锁属性(若为 `NULL`,则使用默认属性) 返回值:成功返回 `0`,失败返回错误码[^1]。 - **静态初始化**: ```c pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ``` 2. **加锁与解锁** ```c int pthread_mutex_lock(pthread_mutex_t *mutex); // 阻塞式加锁 int pthread_mutex_unlock(pthread_mutex_t *mutex); // 解锁 int pthread_mutex_trylock(pthread_mutex_t *mutex); // 非阻塞式加锁 ``` 返回值均为 `0` 表示成功,否则为错误码。 3. **销毁互斥锁** ```c int pthread_mutex_destroy(pthread_mutex_t *mutex); ``` --- #### 使用示例:多线程卖票系统 以下代码模拟 3 个窗口同时卖票,通过互斥锁保护票数共享变量: ```c #include <pthread.h> #include <stdio.h> int tickets = 10; // 总票数 pthread_mutex_t mutex; // 互斥锁 void* sell_ticket(void* arg) { while (1) { pthread_mutex_lock(&mutex); // 加锁 if (tickets > 0) { printf("窗口 %ld 卖出票号 %d\n", (long)arg, tickets--); pthread_mutex_unlock(&mutex); // 解锁 } else { pthread_mutex_unlock(&mutex); break; } } return NULL; } int main() { pthread_t t1, t2, t3; pthread_mutex_init(&mutex, NULL); // 初始化锁 // 创建3个线程 pthread_create(&t1, NULL, sell_ticket, (void*)1); pthread_create(&t2, NULL, sell_ticket, (void*)2); pthread_create(&t3, NULL, sell_ticket, (void*)3); // 等待线程结束 pthread_join(t1, NULL); pthread_join(t2, NULL); pthread_join(t3, NULL); pthread_mutex_destroy(&mutex); // 销毁锁 return 0; } ``` **编译命令**:需链接 `pthread` 库: ```bash g++ program.c -o program -lpthread ``` [^2][^4] --- #### 注意事项 1. **锁的粒度**:加锁范围应尽量小,避免长时间占用锁导致性能下降。 2. **避免死锁**:确保每个 `lock` 都有对应的 `unlock`,且多个锁按固定顺序获取。 3. **错误处理**:检查函数返回值以处理加锁失败等异常情况。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值