面试题答案
一键面试信号处理基本机制
- 信号概念:信号是在软件层次上对中断机制的一种模拟,是一种异步通知机制,用于通知进程发生了某种特定事件。
- 信号处理方式:进程可以选择忽略信号、执行默认动作(如终止进程等)或注册自定义的信号处理函数来处理信号。
注册信号处理函数
在多线程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;
}
主线程和子线程在信号接收处理上的不同
- 主线程:主线程可以像单线程程序一样正常注册信号处理函数,对信号进行处理。如果主线程没有阻塞信号,信号到来时会中断主线程的正常执行,转而去执行信号处理函数。
- 子线程:
- 默认情况:在多线程程序中,信号默认是发送到进程层面,任何线程都可能接收到信号。但如果没有特别处理,信号处理可能会导致未定义行为,因为多个线程同时访问共享资源时可能会产生竞争条件。
- 阻塞与处理:通常会在子线程中使用
pthread_sigmask
函数阻塞掉不希望子线程处理的信号,将信号处理集中在主线程或特定的信号处理线程上。这样可以避免多个线程同时处理信号导致的问题,确保信号处理的一致性和安全性。