MST

星途 面试题库

面试题:C语言信号处理中可重入性的实际问题解决

假设你在一个多线程的C程序中使用信号处理函数,并且该信号处理函数需要访问共享资源,同时要保证可重入性,你会如何设计代码来实现这一点?请描述具体的思路和可能用到的同步机制。
34.6万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试
  1. 设计思路
    • 信号处理函数的选择:选择可重入的函数在信号处理函数中调用。避免使用不可重入的函数,如标准I/O函数(printf等),因为它们可能使用内部静态数据结构,在多线程环境下调用会导致数据竞争和不一致。
    • 共享资源访问控制:确保信号处理函数对共享资源的访问不会干扰其他线程对共享资源的正常操作。
    • 线程安全的数据结构:如果可能,尽量使用线程安全的数据结构来存储共享资源,这样可以减少同步机制的复杂度。
  2. 可能用到的同步机制
    • 互斥锁(Mutex)
      • 在访问共享资源前,使用pthread_mutex_lock函数获取互斥锁。在信号处理函数和其他线程访问共享资源前都要获取这个互斥锁。
      • 例如:
#include <pthread.h>
#include <signal.h>
#include <stdio.h>

pthread_mutex_t mutex;
int shared_variable;

void signal_handler(int signum) {
    pthread_mutex_lock(&mutex);
    // 处理共享资源,例如修改shared_variable
    shared_variable++;
    pthread_mutex_unlock(&mutex);
}

void* thread_function(void* arg) {
    pthread_mutex_lock(&mutex);
    // 线程中访问共享资源
    printf("Thread accessing shared variable: %d\n", shared_variable);
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main() {
    pthread_t thread;
    pthread_mutex_init(&mutex, NULL);
    shared_variable = 0;

    signal(SIGUSR1, signal_handler);

    pthread_create(&thread, NULL, thread_function, NULL);
    pthread_join(thread, NULL);

    pthread_mutex_destroy(&mutex);
    return 0;
}
  • 信号量(Semaphore)
    • 可以使用信号量来控制对共享资源的访问。例如,初始化一个值为1的二元信号量,在访问共享资源前使用sem_wait获取信号量,访问结束后使用sem_post释放信号量。
  • 读写锁(Read - Write Lock)
    • 如果共享资源的访问模式主要是读多写少,可以使用读写锁。信号处理函数如果是写操作,获取写锁(pthread_rwlock_wrlock),其他线程读操作获取读锁(pthread_rwlock_rdlock)。这样可以允许多个线程同时读共享资源,但写操作时会独占资源,避免数据冲突。