MST

星途 面试题库

面试题:C语言Linux信号处理函数参数传递的跨进程共享与同步

在Linux系统中,有多个进程使用C语言编写,进程间通过信号进行通信,要求在信号处理函数间传递共享内存地址作为参数,并且保证参数传递过程中的数据一致性与同步性,描述完整的设计方案并给出核心代码片段。
38.6万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

设计方案

  1. 共享内存设置:使用shmat函数将共享内存段连接到进程地址空间,获取共享内存地址。
  2. 信号处理函数:定义信号处理函数,在信号处理函数中接收共享内存地址参数。
  3. 数据一致性与同步性:利用semaphore(信号量)来保证共享内存访问的同步性。信号量用于控制对共享内存的访问,确保在同一时间只有一个进程能够访问共享内存,从而保证数据一致性。

核心代码片段

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>
#include <semaphore.h>

#define SHM_SIZE 1024
sem_t *sem;

// 共享内存结构体
typedef struct {
    int data[100];
} SharedData;

// 信号处理函数
void signal_handler(int signum, siginfo_t *info, void *context) {
    sem_wait(sem);
    SharedData *shared_mem = (SharedData *)info->si_value.sival_ptr;
    // 处理共享内存数据
    for (int i = 0; i < 100; i++) {
        printf("Received data: %d\n", shared_mem->data[i]);
    }
    sem_post(sem);
}

int main() {
    key_t key = ftok(".", 'a');
    if (key == -1) {
        perror("ftok");
        return 1;
    }

    int shmid = shmget(key, SHM_SIZE, IPC_CREAT | 0666);
    if (shmid == -1) {
        perror("shmget");
        return 1;
    }

    SharedData *shared_mem = (SharedData *)shmat(shmid, NULL, 0);
    if (shared_mem == (void *)-1) {
        perror("shmat");
        return 1;
    }

    sem = sem_open("/semaphore", O_CREAT, 0666, 1);
    if (sem == SEM_FAILED) {
        perror("sem_open");
        return 1;
    }

    struct sigaction sa;
    sa.sa_sigaction = signal_handler;
    sa.sa_flags = SA_SIGINFO;
    sigemptyset(&sa.sa_mask);

    if (sigaction(SIGUSR1, &sa, NULL) == -1) {
        perror("sigaction");
        return 1;
    }

    // 填充共享内存数据
    for (int i = 0; i < 100; i++) {
        shared_mem->data[i] = i;
    }

    union sigval sv;
    sv.sival_ptr = shared_mem;
    if (sigqueue(getppid(), SIGUSR1, sv) == -1) {
        perror("sigqueue");
        return 1;
    }

    // 等待信号处理完成
    sleep(1);

    if (shmdt(shared_mem) == -1) {
        perror("shmdt");
        return 1;
    }

    if (sem_close(sem) == -1) {
        perror("sem_close");
        return 1;
    }

    if (sem_unlink("/semaphore") == -1) {
        perror("sem_unlink");
        return 1;
    }

    if (shmctl(shmid, IPC_RMID, NULL) == -1) {
        perror("shmctl");
        return 1;
    }

    return 0;
}

这段代码实现了以下功能:

  1. 创建共享内存并填充数据。
  2. 定义信号处理函数signal_handler,通过SA_SIGINFO标志在信号处理函数中传递共享内存地址。
  3. 使用信号量确保共享内存访问的同步性。
  4. 发送信号并等待信号处理完成,最后清理共享内存和信号量资源。