MST
星途 面试题库

面试题:C语言复杂信号处理场景

假设在一个长时间运行的C语言守护进程中,需要处理多个信号,包括SIGTERM用于优雅关闭,SIGCHLD用于处理子进程状态变化,SIGALRM用于定期执行某些任务。要求设计一个信号处理框架,使得信号处理函数之间不会相互干扰,并且在不同的信号处理逻辑之间能有效地进行数据共享和同步,描述整体设计思路并给出关键代码片段。
32.1万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 信号处理函数注册:使用 signalsigaction 函数注册不同信号的处理函数。sigaction 更灵活,推荐使用。
  2. 数据共享:通过全局变量在不同信号处理函数间共享数据。
  3. 同步:使用互斥锁(pthread_mutex_t)来保证不同信号处理函数对共享数据的访问同步。
  4. 避免干扰:信号处理函数应尽量简短,复杂操作可通过设置标志位,在主循环中处理。

关键代码片段

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

// 共享数据
int shared_variable = 0;
pthread_mutex_t mutex;

// SIGTERM 处理函数
void handle_sigterm(int signum) {
    pthread_mutex_lock(&mutex);
    // 进行优雅关闭的逻辑,例如清理资源
    printf("Received SIGTERM, performing graceful shutdown...\n");
    // 可以设置标志位,让主循环进行具体清理
    pthread_mutex_unlock(&mutex);
}

// SIGCHLD 处理函数
void handle_sigchld(int signum) {
    pthread_mutex_lock(&mutex);
    // 处理子进程状态变化,例如回收子进程资源
    printf("Received SIGCHLD, handling child process status change...\n");
    // 可在这里更新共享数据
    pthread_mutex_unlock(&mutex);
}

// SIGALRM 处理函数
void handle_sigalrm(int signum) {
    pthread_mutex_lock(&mutex);
    // 定期执行某些任务
    printf("Received SIGALRM, performing periodic task...\n");
    // 更新共享数据
    shared_variable++;
    pthread_mutex_unlock(&mutex);
}

int main() {
    struct sigaction sa;

    // 初始化互斥锁
    pthread_mutex_init(&mutex, NULL);

    // 注册 SIGTERM 信号处理函数
    sa.sa_handler = handle_sigterm;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction(SIGTERM, &sa, NULL);

    // 注册 SIGCHLD 信号处理函数
    sa.sa_handler = handle_sigchld;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction(SIGCHLD, &sa, NULL);

    // 注册 SIGALRM 信号处理函数
    sa.sa_handler = handle_sigalrm;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction(SIGALRM, &sa, NULL);

    // 设置定时器,定期发送 SIGALRM 信号
    alarm(5);

    // 主循环
    while (1) {
        pthread_mutex_lock(&mutex);
        // 主循环可以检查共享数据并进行相应处理
        printf("Shared variable: %d\n", shared_variable);
        pthread_mutex_unlock(&mutex);
        sleep(1);
    }

    // 清理互斥锁
    pthread_mutex_destroy(&mutex);

    return 0;
}