MST

星途 面试题库

面试题:C语言中在多线程环境下信号处理的基础机制

在Linux环境下,使用C语言进行多线程编程时,简述信号处理的基本机制。比如,如何在多线程程序中注册一个信号处理函数,并且说明主线程和子线程在信号接收处理上有什么不同?
26.5万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

信号处理基本机制

  1. 信号概念:信号是在软件层次上对中断机制的一种模拟,是一种异步通知机制,用于通知进程发生了某种特定事件。
  2. 信号处理方式:进程可以选择忽略信号、执行默认动作(如终止进程等)或注册自定义的信号处理函数来处理信号。

注册信号处理函数

在多线程C语言程序(Linux环境)中,一般使用pthread_sigmask函数来设置线程的信号掩码,以及sigaction函数来注册信号处理函数。示例代码如下:

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

// 信号处理函数
void signal_handler(int signum) {
    printf("Caught signal %d\n", signum);
}

void* thread_function(void* arg) {
    // 阻塞SIGINT信号
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, SIGINT);
    pthread_sigmask(SIG_BLOCK, &set, NULL);

    while (1) {
        // 线程工作
    }
    return NULL;
}

int main() {
    pthread_t thread;
    // 创建线程
    pthread_create(&thread, NULL, thread_function, NULL);

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

    // 主线程等待信号
    while (1) {
        // 主线程工作
    }

    pthread_join(thread, NULL);
    return 0;
}

主线程和子线程在信号接收处理上的不同

  1. 主线程:主线程可以像单线程程序一样正常注册信号处理函数,对信号进行处理。如果主线程没有阻塞信号,信号到来时会中断主线程的正常执行,转而去执行信号处理函数。
  2. 子线程
    • 默认情况:在多线程程序中,信号默认是发送到进程层面,任何线程都可能接收到信号。但如果没有特别处理,信号处理可能会导致未定义行为,因为多个线程同时访问共享资源时可能会产生竞争条件。
    • 阻塞与处理:通常会在子线程中使用pthread_sigmask函数阻塞掉不希望子线程处理的信号,将信号处理集中在主线程或特定的信号处理线程上。这样可以避免多个线程同时处理信号导致的问题,确保信号处理的一致性和安全性。