在 Linux C 编程中,mutex(互斥锁)是用于线程同步的重要机制,确保多个线程在访问共享资源时不会发生竞态条件(race condition),Linux 提供了 POSIX 线程库(pthreads),其中包含了对 mutex 的支持。
以下是关于 Linux C 中 mutex 的基本概念、常用函数以及使用示例:
Mutex 的基本概念
- 互斥锁(Mutex):是一种同步原语,用于保护共享资源,确保同一时间只有一个线程可以访问该资源。
- 特点:
- 如果一个线程尝试获取已经被其他线程持有的 mutex,则该线程会被阻塞,直到 mutex 被释放。
- 每个 mutex 都有一个状态:已锁定(locked)或未锁定(unlocked)。
常用 Mutex 函数
POSIX 线程库提供了一组函数来操作 mutex:
(1) 初始化 Mutex
#include <pthread.h> pthread_mutex_t mutex; // 静态初始化 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 动态初始化 int pthread_mutex_init(pthread_mutex_t mutex, const pthread_mutexattr_t attr);
PTHREAD_MUTEX_INITIALIZER是静态初始化宏。
pthread_mutex_init用于动态初始化,可以指定属性(如默认属性为 NULL)。
(2) 锁定 Mutex
int pthread_mutex_lock(pthread_mutex_t mutex);
- mutex 未被锁定,则当前线程获取锁并继续执行。
- mutex 已被锁定,则当前线程会被阻塞,直到 mutex 被释放。
(3) 尝试锁定 Mutex
int pthread_mutex_trylock(pthread_mutex_t mutex);
- mutex 未被锁定,则获取锁并返回 0。
- mutex 已被锁定,则立即返回
EBUSY,不会阻塞。
(4) 解锁 Mutex
int pthread_mutex_unlock(pthread_mutex_t mutex);
- 释放 mutex,允许其他线程获取锁。
(5) 销毁 Mutex
int pthread_mutex_destroy(pthread_mutex_t mutex);
- 用于释放 mutex 占用的资源。
Mutex 的使用示例
以下是一个简单的多线程程序,演示如何使用 mutex 保护共享资源:
#include <stdio.h> #include<pthread.h> // 共享资源 int counter = 0; // 定义 mutex pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 线程函数 void increment_counter(void arg) { for (int i = 0; i < 100000; i++) { // 锁定 mutex pthread_mutex_lock(&mutex); // 修改共享资源 counter++; // 解锁 mutex pthread_mutex_unlock(&mutex); } return NULL; } int main() { pthread_t thread1, thread2; // 创建两个线程 pthread_create(&thread1, NULL, increment_counter, NULL); pthread_create(&thread2, NULL, increment_counter, NULL); // 等待线程结束 pthread_join(thread1, NULL); pthread_join(thread2, NULL); // 输出结果 printf("Final counter value: %dn", counter); // 销毁 mutex pthread_mutex_destroy(&mutex); return 0; }
编译和运行
gcc -o mutex_example mutex_example.c -lpthread ./mutex_example
输出
Final counter value: 200000
注意事项
-
避免死锁:
- 确保所有线程以相同的顺序获取多个 mutex。
- 使用
pthread_mutex_trylock可以避免死锁。
-
性能优化:
- 尽量减少持有 mutex 的时间,只在必要时加锁。
- 使用更细粒度的锁(如分段锁)来提高并发性能。
-
异常处理:
- 在多线程程序中,确保即使发生异常也能正确释放 mutex,可以使用
__attribute__((cleanup))或手动管理锁的状态。
- 在多线程程序中,确保即使发生异常也能正确释放 mutex,可以使用
-
条件变量配合使用:
- 如果需要等待某个条件满足后再执行操作,可以结合
pthread_cond_t使用。
- 如果需要等待某个条件满足后再执行操作,可以结合
扩展:Mutex 属性
POSIX 提供了 pthread_mutexattr_t 来定义 mutex 的属性,
- 类型:普通锁、递归锁、检错锁等。
- 进程共享:是否可以在不同进程间共享。
示例:
pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); // 递归锁 pthread_mutex_t recursive_mutex; pthread_mutex_init(&recursive_mutex, &attr); pthread_mutexattr_destroy(&attr);
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/486663.html



