MST
星途 面试题库

面试题:C语言中Linux异步I/O异步通知机制的信号实现

在Linux环境下,使用C语言实现基于信号的异步I/O异步通知机制,简单描述实现步骤并给出关键代码片段。假设你要监控一个文件描述符的读事件,当有数据可读时,通过信号通知主程序。
33.7万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

实现步骤

  1. 注册信号处理函数:使用 signalsigaction 函数注册信号处理函数,该函数将在有数据可读时被调用。
  2. 设置文件描述符为异步I/O模式:使用 fcntl 函数的 F_SETOWNF_SETFL 操作,将文件描述符设置为异步I/O模式,并指定接收信号的进程ID。
  3. 启用信号通知:通过 fcntl 函数设置 O_ASYNC 标志来启用异步I/O通知。
  4. 在信号处理函数中处理读事件:在信号处理函数中读取数据并进行相应处理。

关键代码片段

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>

// 信号处理函数
void signal_handler(int signum) {
    char buffer[1024];
    int fd = STDIN_FILENO; // 假设监控标准输入
    ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
    if (bytes_read > 0) {
        buffer[bytes_read] = '\0';
        printf("Received data: %s", buffer);
    }
}

int main() {
    int fd = STDIN_FILENO; // 假设监控标准输入
    // 注册信号处理函数
    if (signal(SIGIO, signal_handler) == SIG_ERR) {
        perror("signal");
        exit(EXIT_FAILURE);
    }
    // 设置文件描述符为异步I/O模式
    if (fcntl(fd, F_SETOWN, getpid()) == -1) {
        perror("fcntl F_SETOWN");
        exit(EXIT_FAILURE);
    }
    int flags = fcntl(fd, F_GETFL, 0);
    if (flags == -1) {
        perror("fcntl F_GETFL");
        exit(EXIT_FAILURE);
    }
    if (fcntl(fd, F_SETFL, flags | O_ASYNC) == -1) {
        perror("fcntl F_SETFL");
        exit(EXIT_FAILURE);
    }
    // 启用信号通知
    if (fcntl(fd, F_SETFL, O_ASYNC) == -1) {
        perror("fcntl O_ASYNC");
        exit(EXIT_FAILURE);
    }
    // 主程序循环
    while (1) {
        sleep(1);
    }
    return 0;
}