优化Linux互斥锁性能瓶颈的措施
- 减少锁粒度:
- 原理:将大的临界区划分成多个小的临界区,每个小临界区使用单独的锁进行保护。这样不同的线程可以同时访问不同的临界区,提高并发度。
- 示例:假设原来有一个函数处理多个资源,对整个函数加锁。
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int resource1 = 0;
int resource2 = 0;
// 原函数,整个函数加锁
void old_function() {
pthread_mutex_lock(&mutex);
// 处理resource1和resource2
resource1++;
resource2++;
pthread_mutex_unlock(&mutex);
}
// 优化后,分别对不同资源加锁
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
void new_function() {
pthread_mutex_lock(&mutex1);
resource1++;
pthread_mutex_unlock(&mutex1);
pthread_mutex_lock(&mutex2);
resource2++;
pthread_mutex_unlock(&mutex2);
}
- 读写锁的使用:
- 原理:如果临界区主要是读操作,使用读写锁(
pthread_rwlock
)可以允许多个线程同时读,只有写操作时才需要独占锁。读操作之间不互斥,提高了并发读的性能。
- 示例:
#include <pthread.h>
#include <stdio.h>
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
int shared_data = 0;
// 读线程函数
void* read_thread(void* arg) {
pthread_rwlock_rdlock(&rwlock);
printf("Read data: %d\n", shared_data);
pthread_rwlock_unlock(&rwlock);
return NULL;
}
// 写线程函数
void* write_thread(void* arg) {
pthread_rwlock_wrlock(&rwlock);
shared_data++;
printf("Write data: %d\n", shared_data);
pthread_rwlock_unlock(&rwlock);
return NULL;
}
可替代互斥锁的同步机制
- 信号量(Semaphore):
- 适用场景:适用于需要控制并发访问数量的场景,例如连接池的管理,控制同时连接的最大数量。
- 优势:可以灵活控制同时进入临界区的线程数量,比互斥锁更具灵活性。
- 示例:
#include <semaphore.h>
#include <pthread.h>
#include <stdio.h>
sem_t semaphore;
int shared_resource = 0;
// 线程函数
void* thread_function(void* arg) {
sem_wait(&semaphore);
shared_resource++;
printf("Thread incremented shared resource: %d\n", shared_resource);
sem_post(&semaphore);
return NULL;
}
- 条件变量(Condition Variable):
- 适用场景:用于线程间的同步,当某个条件满足时,通知等待的线程。常用于生产者 - 消费者模型。
- 优势:可以避免线程不必要的循环等待,节省CPU资源。
- 示例:
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int data_ready = 0;
int shared_data = 0;
// 生产者线程函数
void* producer(void* arg) {
pthread_mutex_lock(&mutex);
shared_data = 42;
data_ready = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
return NULL;
}
// 消费者线程函数
void* consumer(void* arg) {
pthread_mutex_lock(&mutex);
while (!data_ready) {
pthread_cond_wait(&cond, &mutex);
}
printf("Consumed data: %d\n", shared_data);
pthread_mutex_unlock(&mutex);
return NULL;
}