MST

星途 面试题库

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

在一个多线程的C程序运行于Linux系统中,主线程创建了若干子线程。现在要求主线程在执行一段关键代码时,屏蔽所有信号以免干扰,而子线程继续正常响应信号。请详细阐述实现思路,并给出主要的代码框架(涉及信号屏蔽相关函数调用和线程操作)。
24.9万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试
  1. 实现思路
    • 使用pthread_sigmask函数来设置信号屏蔽。在主线程中屏蔽信号,在子线程中恢复默认的信号处理方式(不屏蔽信号)。
    • 主线程创建子线程时,需要确保子线程继承主线程的信号屏蔽状态(默认是继承的),然后在子线程中解除对信号的屏蔽。
  2. 主要代码框架
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>

// 子线程函数
void* child_thread(void* arg) {
    sigset_t set;
    // 清空信号集
    sigemptyset(&set);
    // 设置子线程不屏蔽任何信号
    pthread_sigmask(SIG_SETMASK, &set, NULL);
    while(1) {
        // 子线程正常工作内容
        printf("Child thread is running...\n");
        sleep(1);
    }
    return NULL;
}

int main() {
    pthread_t tid;
    sigset_t set;

    // 清空信号集
    sigemptyset(&set);
    // 添加要屏蔽的信号,这里以SIGINT为例
    sigaddset(&set, SIGINT);

    // 主线程屏蔽信号
    pthread_sigmask(SIG_BLOCK, &set, NULL);

    // 创建子线程
    if (pthread_create(&tid, NULL, child_thread, NULL) != 0) {
        perror("pthread_create");
        return 1;
    }

    // 主线程执行关键代码,这里以一个循环模拟
    for (int i = 0; i < 5; i++) {
        printf("Main thread is running critical code...\n");
        sleep(1);
    }

    // 主线程关键代码执行完毕,恢复信号处理(这里只是示例,实际可能根据需求调整)
    pthread_sigmask(SIG_UNBLOCK, &set, NULL);

    // 等待子线程结束
    pthread_join(tid, NULL);

    return 0;
}

在上述代码中:

  • main函数中,主线程先屏蔽SIGINT信号,然后创建子线程。
  • 子线程函数child_thread中,解除对信号的屏蔽,这样子线程可以正常响应信号。
  • 主线程执行完关键代码后,解除对信号的屏蔽。最后主线程等待子线程结束。