MST

星途 面试题库

面试题:C语言Linux信号处理函数错误下的程序健壮性

假设你正在开发一个多线程的Linux C程序,在信号处理函数中需要对共享资源进行操作。请描述可能会出现哪些错误,如何通过合适的同步机制和错误处理策略来保证程序的健壮性和数据一致性。
11.6万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

可能出现的错误

  1. 竞态条件:多个线程同时访问和修改共享资源,导致数据不一致。因为信号处理函数可能在任意时刻被调用,若与其他线程同时操作共享资源,就会产生这种问题。
  2. 未定义行为:信号处理函数执行时可能打断正常的程序流程,若此时共享资源处于部分修改的中间状态,可能导致未定义行为。

同步机制

  1. 互斥锁(Mutex):在信号处理函数和其他线程访问共享资源前加锁,访问结束后解锁。例如:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void signal_handler(int signum) {
    pthread_mutex_lock(&mutex);
    // 操作共享资源
    pthread_mutex_unlock(&mutex);
}
  1. 读写锁(Read - Write Lock):如果共享资源读操作多,写操作少,可以使用读写锁。信号处理函数进行写操作时,获取写锁;其他线程读操作时获取读锁。
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;

void signal_handler(int signum) {
    pthread_rwlock_wrlock(&rwlock);
    // 操作共享资源
    pthread_rwlock_unlock(&rwlock);
}

错误处理策略

  1. 检查函数返回值:在调用同步函数(如pthread_mutex_lockpthread_rwlock_wrlock等)时,检查其返回值。若返回非零值,表示操作失败,根据返回值进行相应处理。例如:
int ret;
ret = pthread_mutex_lock(&mutex);
if (ret != 0) {
    // 处理错误,如记录日志、进行恢复操作等
}
  1. 使用sigprocmask函数:在主线程中暂时屏蔽信号,在对共享资源操作的临界区前后分别恢复信号,这样可以避免信号处理函数在临界区内被调用。
sigset_t newset, oldset;
sigemptyset(&newset);
sigaddset(&newset, SIGUSR1);

// 屏蔽信号
sigprocmask(SIG_BLOCK, &newset, &oldset);
// 操作共享资源
// 恢复信号
sigprocmask(SIG_SETMASK, &oldset, NULL);