MST

星途 面试题库

面试题:C语言中Linux互斥锁性能优化与替代方案

在高并发场景下,使用C语言的Linux互斥锁可能会带来性能瓶颈。阐述针对这种性能瓶颈可采取的优化措施,以及在某些场景下可以替代互斥锁的同步机制,并详细说明其适用场景和优势,给出相关代码示例辅助说明。
47.9万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

优化Linux互斥锁性能瓶颈的措施

  1. 减少锁粒度
    • 原理:将大的临界区划分成多个小的临界区,每个小临界区使用单独的锁进行保护。这样不同的线程可以同时访问不同的临界区,提高并发度。
    • 示例:假设原来有一个函数处理多个资源,对整个函数加锁。
#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);
}
  1. 读写锁的使用
    • 原理:如果临界区主要是读操作,使用读写锁(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;
}

可替代互斥锁的同步机制

  1. 信号量(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;
}
  1. 条件变量(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;
}