MST

星途 面试题库

面试题:C语言读写锁的性能优化场景

假设你正在开发一个多线程的日志记录系统,读操作远多于写操作,使用C语言结合Linux的读写锁机制,描述如何设计数据结构和操作逻辑以最大程度提升并发性能,并说明这样设计的理由。
40.6万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

数据结构设计

  1. 日志结构体
typedef struct {
    char log_message[1024]; // 假设日志消息最大长度为1024字节
    time_t timestamp; // 记录日志产生的时间戳
} LogEntry;
  1. 日志缓冲区
typedef struct {
    LogEntry *entries[1000]; // 假设缓冲区大小为1000条日志
    int head;
    int tail;
    pthread_rwlock_t rwlock;
} LogBuffer;

操作逻辑设计

  1. 初始化
void init_log_buffer(LogBuffer *buffer) {
    buffer->head = 0;
    buffer->tail = 0;
    pthread_rwlock_init(&buffer->rwlock, NULL);
}
  1. 写操作
void write_log(LogBuffer *buffer, const char *message) {
    LogEntry *entry = (LogEntry *)malloc(sizeof(LogEntry));
    if (entry == NULL) {
        // 处理内存分配失败
        return;
    }
    strcpy(entry->log_message, message);
    entry->timestamp = time(NULL);

    pthread_rwlock_wrlock(&buffer->rwlock);
    buffer->entries[buffer->tail] = entry;
    buffer->tail = (buffer->tail + 1) % 1000;
    pthread_rwlock_unlock(&buffer->rwlock);
}
  1. 读操作
void read_log(LogBuffer *buffer, int index, LogEntry **entry) {
    pthread_rwlock_rdlock(&buffer->rwlock);
    if (index >= 0 && index < 1000) {
        *entry = buffer->entries[index];
    } else {
        *entry = NULL;
    }
    pthread_rwlock_unlock(&buffer->rwlock);
}

设计理由

  1. 读写锁机制:由于读操作远多于写操作,使用读写锁可以允许多个线程同时进行读操作,而写操作时则独占锁,避免了读写冲突和写写冲突,提升了并发性能。
  2. 环形缓冲区:采用环形缓冲区数据结构,在写操作时通过移动tail指针来添加新日志,读操作通过index来获取特定位置的日志。这种方式不需要频繁地重新分配内存,减少了内存碎片和分配开销,并且读写操作可以并发进行,进一步提升了系统的并发性能。同时,环形缓冲区的实现简单高效,适合在多线程环境下使用。