MST

星途 面试题库

面试题:C语言多线程异常处理与资源管理

在Linux C语言多线程应用中,存在多个线程共享一些资源(如文件描述符、内存区域等),当某个线程发生异常(如段错误、除零错误等)时,如何确保这些共享资源能够被正确释放,避免资源泄漏。请从设计架构和代码实现两方面阐述解决方案。
21.3万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

设计架构方面

  1. 资源管理模块
    • 设计一个独立的资源管理模块,负责所有共享资源的分配与释放。每个线程在使用共享资源前,通过该模块获取资源,使用完毕后,再通过该模块释放资源。这样当某个线程异常时,资源管理模块可以统一处理资源的释放。
    • 资源管理模块可以采用类似池化的机制,预先分配一定数量的共享资源,线程需要时从池中获取,使用完归还到池中,便于集中管理。
  2. 异常处理机制
    • 为每个线程设置异常处理函数。在异常处理函数中,将线程异常的信息传递给资源管理模块,资源管理模块根据这些信息来释放该线程持有的共享资源。
    • 可以使用信号处理机制,例如对于段错误(SIGSEGV)、除零错误(SIGFPE)等信号,注册相应的信号处理函数,在函数中进行资源释放相关操作。
  3. 线程安全设计
    • 使用互斥锁(pthread_mutex_t)、读写锁(pthread_rwlock_t)等同步机制来保护共享资源,确保在同一时间只有一个线程可以访问共享资源,避免多个线程同时操作共享资源导致的数据不一致或其他错误。同时,在资源释放过程中也需要使用这些同步机制,保证释放操作的原子性和线程安全性。

代码实现方面

  1. 资源管理模块实现
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

// 假设共享资源是一个简单的整数数组
#define RESOURCE_SIZE 10
int shared_resource[RESOURCE_SIZE];
pthread_mutex_t resource_mutex;

// 初始化资源管理模块
void init_resource_manager() {
    pthread_mutex_init(&resource_mutex, NULL);
    // 初始化共享资源数组
    for (int i = 0; i < RESOURCE_SIZE; i++) {
        shared_resource[i] = i;
    }
}

// 获取共享资源
int* get_shared_resource() {
    pthread_mutex_lock(&resource_mutex);
    return shared_resource;
}

// 释放共享资源
void release_shared_resource() {
    pthread_mutex_unlock(&resource_mutex);
}

// 销毁资源管理模块
void destroy_resource_manager() {
    pthread_mutex_destroy(&resource_mutex);
}
  1. 线程异常处理实现
#include <signal.h>
#include <ucontext.h>
#include <pthread.h>

// 线程异常处理函数
void signal_handler(int signum, siginfo_t *info, void *context) {
    // 获取当前线程ID
    pthread_t current_thread = pthread_self();
    // 这里可以添加日志记录,记录异常线程ID和异常信号
    printf("Thread %lu got signal %d\n", (unsigned long)current_thread, signum);
    // 调用资源管理模块释放资源
    release_shared_resource();
}

// 线程函数示例
void* thread_function(void* arg) {
    // 注册信号处理函数
    struct sigaction sa;
    sa.sa_sigaction = signal_handler;
    sa.sa_flags = SA_SIGINFO;
    sigemptyset(&sa.sa_mask);
    sigaction(SIGSEGV, &sa, NULL);
    sigaction(SIGFPE, &sa, NULL);

    int* resource = get_shared_resource();
    // 模拟异常操作,例如除零错误
    int result = 1 / 0; 
    release_shared_resource();
    return NULL;
}

int main() {
    init_resource_manager();
    pthread_t thread;
    pthread_create(&thread, NULL, thread_function, NULL);
    pthread_join(thread, NULL);
    destroy_resource_manager();
    return 0;
}

上述代码实现了一个简单的资源管理模块,并在每个线程中注册了异常处理函数。当线程发生段错误或除零错误等异常时,会调用信号处理函数,在函数中释放该线程持有的共享资源。同时,通过互斥锁保证了共享资源访问的线程安全性。