Brief description of signal-driven io model

1. What is signal driven IO?
The signal drives IO, and a callback function is set in the kernel in advance. When an event occurs, the kernel uses a signal (SIGIO) to notify the process to process (run the callback function). It can also be regarded as a kind of asynchronous IO, because the detection of whether fd has data and whether it is readable and writable is done in two processes.
Its advantage is that the process is not blocked before receiving the SIGIO signal and can do other things.
Its disadvantage is that when the amount of data becomes large, the signal is generated too frequently, and the performance will be very low. The kernel needs to continuously copy data to user mode.
2. Reference code
General signal drive io for udp

#include <fcntl.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

int socket_fd = 0;

void do_sometime(int signal) {
    
    
    struct sockaddr_in cli_addr;
    int clilen = sizeof(cli_addr);
    int clifd = 0;

    char buffer[256] = {
    
    0};
    int len = recvfrom(socket_fd, buffer, 256, 0, (struct sockaddr *)&cli_addr,
                       (socklen_t)&clilen);
    printf("Mes:%s", buffer);

    sendto(socket_fd, buffer, len, 0, (struct sockaddr *)&cli_addr, clilen);
}

int main(int argc, char const *argv[]) {
    
    
    socket_fd = socket(AF_INET, SOCK_DGRAM, 0);

    struct sigaction act;
    act.sa_flags = 0;
    act.sa_handler = do_sometime;
    sigaction(SIGIO, &act, NULL);  // 监听IO事件

    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));

    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(8888);
    servaddr.sin_addr.s_addr = INADDR_ANY;

    //设置将要在socket_fd上接收SIGIO的进程
    fcntl(socket_fd, F_SETOWN, getpid());

    int flags = fcntl(socket_fd, F_GETFL, 0);
    flags |= O_NONBLOCK;
    flags |= O_ASYNC;
    fcntl(socket_fd, F_SETFL, flags);

    bind(socket_fd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    while (1) sleep(1);

    close(socket_fd);

    return 0;
}

Guess you like

Origin blog.csdn.net/niu91/article/details/109706893