MST
星途 面试题库

面试题:C语言中Linux信号处理函数与并发问题基础

在Linux环境下用C语言编程,假设我们有一个信号处理函数`sig_handler`用于处理`SIGINT`信号,在主程序中有一个循环不断执行任务。当`SIGINT`信号到来时,信号处理函数会修改一个全局变量`flag`。请描述可能出现的并发问题,并说明如何使用`volatile`关键字来缓解这个问题。
14.3万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

可能出现的并发问题

  1. 缓存一致性问题:在多处理器或具有缓存的系统中,CPU可能会将全局变量flag缓存到自己的高速缓存中。主程序循环执行任务时,可能一直在使用缓存中的旧值,而信号处理函数修改的flag值在主存中,导致主程序不能及时感知到flag的变化。
  2. 指令重排问题:编译器为了优化代码性能,可能会对指令进行重排。例如,主程序中对flag的读取操作可能被提前到循环的前面,导致即使flag被信号处理函数修改,主程序也不会在循环中及时检测到变化。

使用volatile关键字缓解问题

volatile关键字告诉编译器,该变量的值可能会在程序的控制流之外被改变。在声明全局变量flag时使用volatile关键字,如下所示:

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

volatile int flag = 0;

void sig_handler(int signum) {
    flag = 1;
}

int main() {
    signal(SIGINT, sig_handler);

    while (1) {
        // 执行任务
        if (flag) {
            printf("Received SIGINT, exiting loop...\n");
            break;
        }
    }

    return 0;
}

这样声明后,编译器不会对flag进行缓存优化,每次访问flag时都会从内存中读取最新值,避免了缓存一致性问题。同时,volatile也会阻止编译器对涉及flag的指令进行重排,确保程序按照代码逻辑执行,从而使主程序能及时感知到flag的变化。