MST
星途 面试题库

面试题:并发与同步:信号量在多线程同步中的复杂应用

假设你正在开发一个多线程的文件服务器,每个线程负责处理一个客户端请求,文件服务器有一定数量的可用文件描述符。使用信号量来控制对文件描述符的访问,确保不会有超过系统限制数量的线程同时获取文件描述符。请描述实现思路并给出关键代码片段(语言不限)。
46.1万 热度难度
操作系统并发与同步

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 初始化一个信号量,其初始值为系统允许的最大文件描述符数量。
  2. 当一个线程需要获取文件描述符时,先尝试获取信号量。如果信号量的值大于0,线程获取成功,信号量值减1,线程可以使用文件描述符;否则线程等待,直到信号量值变为大于0。
  3. 当线程使用完文件描述符后,释放信号量,使信号量值加1,以便其他线程可以获取。

关键代码片段(以Python为例,使用multiprocessing模块中的Semaphore

import multiprocessing


# 假设系统允许的最大文件描述符数量为10
max_file_descriptors = 10
semaphore = multiprocessing.Semaphore(max_file_descriptors)


def handle_client_request():
    semaphore.acquire()
    try:
        # 这里处理获取文件描述符并处理客户端请求的逻辑
        print("线程获取到文件描述符,开始处理请求")
    finally:
        semaphore.release()
        print("线程释放文件描述符")


if __name__ == '__main__':
    # 创建多个线程模拟处理多个客户端请求
    num_threads = 20
    threads = []
    for _ in range(num_threads):
        t = multiprocessing.Process(target=handle_client_request)
        threads.append(t)
        t.start()

    for t in threads:
        t.join()

关键代码片段(以C语言为例,使用POSIX信号量)

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

#define MAX_FILE_DESCRIPTORS 10
sem_t semaphore;

void* handle_client_request(void* arg) {
    sem_wait(&semaphore);
    // 这里处理获取文件描述符并处理客户端请求的逻辑
    printf("线程获取到文件描述符,开始处理请求\n");
    sem_post(&semaphore);
    printf("线程释放文件描述符\n");
    return NULL;
}

int main() {
    sem_init(&semaphore, 0, MAX_FILE_DESCRIPTORS);
    pthread_t threads[20];
    for (int i = 0; i < 20; i++) {
        pthread_create(&threads[i], NULL, handle_client_request, NULL);
    }
    for (int i = 0; i < 20; i++) {
        pthread_join(threads[i], NULL);
    }
    sem_destroy(&semaphore);
    return 0;
}