MST

星途 面试题库

面试题:C语言在Linux下信号恢复的复杂场景应用

假设有一个多线程的C程序运行在Linux系统上,主线程创建了若干子线程。要求主线程能够捕获SIGTERM信号,在信号处理函数中,需要安全地终止所有子线程,然后主线程进行一些清理工作后退出,并且确保信号处理过程中的状态恢复正确,避免资源泄漏。描述整体设计思路并给出关键代码片段。
20.5万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 信号处理函数注册:在主线程中使用signalsigaction函数注册SIGTERM信号的处理函数。
  2. 线程同步:使用互斥锁(mutex)来保护共享资源,确保在信号处理函数和子线程访问共享资源时不会产生竞争条件。
  3. 终止子线程:在信号处理函数中,设置一个标志位,通知所有子线程需要终止。子线程在合适的时机(如循环中检查标志位)检查这个标志位,然后安全地退出。
  4. 清理工作:主线程在所有子线程退出后,进行清理工作,如释放资源等,然后退出。

关键代码片段

#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int should_exit = 0;

// 子线程函数
void* thread_function(void* arg) {
    while (1) {
        pthread_mutex_lock(&mutex);
        if (should_exit) {
            pthread_mutex_unlock(&mutex);
            break;
        }
        pthread_mutex_unlock(&mutex);
        // 子线程工作内容
        printf("子线程正在工作...\n");
        sleep(1);
    }
    pthread_exit(NULL);
}

// SIGTERM信号处理函数
void signal_handler(int signum) {
    pthread_mutex_lock(&mutex);
    should_exit = 1;
    pthread_mutex_unlock(&mutex);
}

int main() {
    pthread_t threads[10];
    int i;

    // 注册SIGTERM信号处理函数
    signal(SIGTERM, signal_handler);

    // 创建子线程
    for (i = 0; i < 10; i++) {
        if (pthread_create(&threads[i], NULL, thread_function, NULL) != 0) {
            perror("pthread_create");
            return 1;
        }
    }

    // 等待信号
    while (!should_exit) {
        sleep(1);
    }

    // 等待所有子线程结束
    for (i = 0; i < 10; i++) {
        if (pthread_join(threads[i], NULL) != 0) {
            perror("pthread_join");
            return 1;
        }
    }

    // 主线程清理工作
    printf("主线程进行清理工作...\n");
    pthread_mutex_destroy(&mutex);

    return 0;
}