MST

星途 面试题库

面试题:C语言信号阻塞机制下多线程场景的信号处理

在一个多线程的C程序中,主线程创建了多个子线程。现在希望主线程阻塞`SIGTERM`信号,而子线程能够正常响应`SIGTERM`信号并进行相应的清理工作。请阐述实现的思路,并写出主要的代码逻辑,包括如何在多线程环境中正确使用信号集和信号阻塞相关函数。
11.2万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 主线程阻塞信号:主线程使用sigprocmask函数阻塞SIGTERM信号,防止主线程在处理其他任务时意外响应SIGTERM
  2. 子线程处理信号:子线程使用pthread_sigmask函数设置为不阻塞SIGTERM信号,同时创建一个信号处理函数,当SIGTERM信号到达时,子线程能够捕获并执行清理工作。

主要代码逻辑

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

// 信号处理函数
void sig_handler(int signum) {
    printf("子线程收到SIGTERM信号,开始清理工作...\n");
    // 在这里添加清理代码
}

void* thread_func(void* arg) {
    // 子线程设置为不阻塞SIGTERM信号
    sigset_t sigset;
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGTERM);
    pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);

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

    // 模拟子线程工作
    while (1) {
        printf("子线程正在工作...\n");
        sleep(1);
    }
    return NULL;
}

int main() {
    pthread_t tid;
    // 主线程阻塞SIGTERM信号
    sigset_t sigset;
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGTERM);
    sigprocmask(SIG_BLOCK, &sigset, NULL);

    // 创建子线程
    pthread_create(&tid, NULL, thread_func, NULL);

    // 主线程模拟其他工作
    while (1) {
        printf("主线程正在工作...\n");
        sleep(1);
    }

    // 等待子线程结束(这里不会执行到,因为主线程在while循环中)
    pthread_join(tid, NULL);
    return 0;
}

在上述代码中:

  1. 主线程:通过sigprocmask函数阻塞SIGTERM信号,然后创建子线程。
  2. 子线程:首先通过pthread_sigmask函数设置为不阻塞SIGTERM信号,接着注册sig_handler函数作为SIGTERM信号的处理函数,然后模拟子线程的工作。当收到SIGTERM信号时,sig_handler函数会被调用执行清理工作。