1. 互斥锁的概念
互斥锁(Mutual Exclusion Lock),简称mutex,是一种用于保护共享资源的并发控制机制。在多线程编程中,若不对共享资源进行合适的并发控制,可能会导致数据混乱,甚至产生严重的并发访问问题。互斥锁的作用就是在同一时间只允许一个线程访问共享资源,当一个线程持有锁时,其他线程需要等待锁的释放才能访问。
2. 互斥锁的实现方式
在Linux中,实现互斥锁的方式有多种,常见的有以下两种:
2.1. pthread_mutex_t
pthread_mutex_t 是一种基于线程库(pthread)实现的互斥锁,是 Linux 下最常用的互斥锁类型之一。它提供了一些用于操作互斥锁的函数,例如初始化锁(pthread_mutex_init)、加锁(pthread_mutex_lock)和解锁(pthread_mutex_unlock)等。
#include <pthread.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// 线程1执行的函数
void* thread_func1(void* arg) {
// 加锁
pthread_mutex_lock(&mutex);
// 访问共享资源
// 解锁
pthread_mutex_unlock(&mutex);
return NULL;
}
// 线程2执行的函数
void* thread_func2(void* arg) {
// 加锁
pthread_mutex_lock(&mutex);
// 访问共享资源
// 解锁
pthread_mutex_unlock(&mutex);
return NULL;
}
2.2. std::mutex
std::mutex 是 C++11 标准库提供的互斥锁类型,用于实现多线程间的互斥访问。它与 pthread_mutex_t 类似,也提供了初始化锁(std::mutex::mutex)、加锁(std::mutex::lock)和解锁(std::mutex::unlock)等操作函数。
#include <mutex>
std::mutex mutex;
// 线程1执行的函数
void thread_func1() {
// 加锁
mutex.lock();
// 访问共享资源
// 解锁
mutex.unlock();
}
// 线程2执行的函数
void thread_func2() {
// 加锁
mutex.lock();
// 访问共享资源
// 解锁
mutex.unlock();
}
3. 互斥锁的读写控制
除了实现基本的互斥访问,有时我们需要在同时有多个读取者线程时允许并发访问,而在写入者线程访问时需要进行互斥控制。下面介绍两种常见的读写互斥锁实现方式。
3.1. pthread_rwlock_t
pthread_rwlock_t 是一种读写锁类型,通过 Pthreads 库提供,用于实现读者写者问题的并发控制。读写锁允许多个读者线程同时访问共享资源,但在写者线程访问时需要进行独占。使用读写锁时,需要注意读者线程和写者线程之间的竞争条件,确保数据的一致性。
#include <pthread.h>
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
// 读取者线程执行的函数
void* reader_func(void* arg) {
// 加读锁
pthread_rwlock_rdlock(&rwlock);
// 访问共享资源
// 解锁
pthread_rwlock_unlock(&rwlock);
return NULL;
}
// 写入者线程执行的函数
void* writer_func(void* arg) {
// 加写锁
pthread_rwlock_wrlock(&rwlock);
// 访问共享资源
// 解锁
pthread_rwlock_unlock(&rwlock);
return NULL;
}
3.2. std::shared_mutex
std::shared_mutex 是 C++17 标准库提供的一种读写锁类型,用于实现多线程环境下的读写互斥。它允许多个读取者线程并发访问共享资源,但在写入者线程访问时进行独占。
#include <shared_mutex>
std::shared_mutex rwlock;
// 读取者线程执行的函数
void reader_func() {
// 加读锁
rwlock.lock_shared();
// 访问共享资源
// 解锁
rwlock.unlock_shared();
}
// 写入者线程执行的函数
void writer_func() {
// 加写锁
rwlock.lock();
// 访问共享资源
// 解锁
rwlock.unlock();
}
4. 总结
互斥锁是一种重要的并发控制机制,可以有效地保护共享资源,防止多个线程同时访问导致的数据错误。在 Linux 环境下,常见的互斥锁实现方式包括 pthread_mutex_t、std::mutex、pthread_rwlock_t 和 std::shared_mutex。根据具体的并发需求,选择适合的互斥锁类型来实现读写控制,确保多线程程序的正确性和性能。