zoukankan      html  css  js  c++  java
  • linux epoll学习

    #include <sys/time.h>   /* For portability */
    #include <sys/select.h>
    
    int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
    Returns number of ready file descriptors, 0 on timeout, or –1 on error
    
    #include <sys/select.h>
    void FD_ZERO(fd_set *fdset);
    void FD_SET(int fd, fd_set *fdset);
    void FD_CLR(int fd, fd_set *fdset);
    int FD_ISSET(int fd, fd_set *fdset);
        Returns true (1) if fd is in fdset, or false (0) otherwise
    
    FD_ZERO() initializes the set pointed to by fdset to be empty.
    FD_SET() adds the file descriptor fd to the set pointed to by fdset.
    FD_CLR() removes the file descriptor fd from the set pointed to by fdset.
    FD_ISSET() returns true if the file descriptor fd is a member of the set pointed to
    by fdset.
    
    struct timeval {
        time_t tv_sec;      /* Seconds */
        suseconds_t tv_usec;/* Microseconds (long int) */
    };
    
    typedef struct
    {
        /*XPG4.2requiresthismembername.Otherwiseavoidthename
        fromtheglobalnamespace.*/
        #ifdef__USE_XOPEN
        __fd_maskfds_bits[__FD_SETSIZE/__NFDBITS];
        #define__FDS_BITS(set)((set)->fds_bits)
        #else
        __fd_mask__fds_bits[__FD_SETSIZE/__NFDBITS];
        #define__FDS_BITS(set)((set)->__fds_bits)
        #endif
    }fd_set; /* linux下为 1024/8 = 128 Bytes */
    
    ------------------
    
    
    #include <sys/epoll.h>
    int epoll_create(int size);
        Returns file descriptor on success, or –1 on error
    
    Starting with kernel 2.6.27, Linux supports a new system call, epoll_create1().
    This system call performs the same task as epoll_create(), but drops the obsolete
    size argument and adds a flags argument that can be used to modify the behavior
    of the system call. One flag is currently supported: EPOLL_CLOEXEC, which causes
    the kernel to enable the close-on-exec flag (FD_CLOEXEC) for the new file descriptor.
    This flag is useful for the same reasons as the open() O_CLOEXEC flag described in
    Section 4.3.1
    
    #include <sys/epoll.h>
    int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev);
        Returns 0 on success, or –1 on error
    
    The fd argument identifies which of the file descriptors in the interest list is to have
    its settings modified. This argument can be a file descriptor for a 'pipe, FIFO,
    socket, POSIX message queue, inotify instance, terminal, device, or even another epoll
    descriptor' (i.e., we can build a kind of hierarchy of monitored descriptors). However,
    fd can’t be a file descriptor for a regular file or a directory (the error EPERM results).
    
    
    The op argument specifies the operation to be performed, and has one of the
    following values:
    EPOLL_CTL_ADD
    EPOLL_CTL_MOD
    EPOLL_CTL_DEL
    
    共12字节:
    struct epoll_event {
        uint32_t events;        /* epoll events (bit mask) */
        epoll_data_t data;      /* User data */
    };
    
    The data field of the epoll_event structure is typed as follows:
    typedef union epoll_data {
        void *ptr;      //Pointer to user-defined data 
        int fd;         //File descriptor */
        uint32_t u32;   //32-bit integer */
        uint64_t u64;   //64-bit integer */
    } epoll_data_t;
    
    #include <sys/epoll.h>
    int epoll_wait(int epfd, struct epoll_event *evlist, int maxevents, int timeout);
        Returns number of ready file descriptors, 0 on timeout, or –1 on error
    
    
    Table 63-8: Bit-mask values for the epoll events field Bit
    EPOLLIN             Data other than high-priority data can be read
    EPOLLPRI            High-priority data can be read
    EPOLLRDHUP          Shutdown on peer socket (since Linux 2.6.17)
    EPOLLOUT            Normal data can be written
    EPOLLET             Employ edge-triggered event notification
    EPOLLONESHOT        Disable monitoring after event notification
    EPOLLERR            An error has occurred
    EPOLLHUP            A hangup has occurred
    
    Input to            Returned by
    epoll_ctl()?        epoll_wait()?
    • •
    • •
    • •
    • • 
    • 
    •
     •
     •
    
    // gcc epoll_input_fifo.c lib/error_functions.c lib/get_num.c -Ilib  -o epoll_input_fifo.out
    #include <sys/epoll.h>
    #include <fcntl.h>
    #include "tlpi_hdr.h"
    
    #define MAX_BUF 1000
    #define MAX_EVENTS 5
    
    int main(int argc, char *argv[]){
        int epfd, ready, fd, s, j, numOpenFds;
        struct epoll_event ev;
        struct epoll_event evlist[MAX_EVENTS];
        char buf[MAX_BUF];
    
        printf("EPOLLIN: 0x%x
    ", EPOLLIN);
        printf("EPOLLHUP: 0x%x
    ", EPOLLHUP);
        printf("EPOLLERR: 0x%x
    ", EPOLLERR);
    
        if (argc < 2 || strcmp(argv[1], "--help") == 0)
            usageErr("%s file...
    ", argv[0]);
    
        epfd = epoll_create(argc-1);
        if(epfd == -1)
            errExit("epoll_create");
    
        for(j = 1; j < argc; j++){
            fd = open(argv[j], O_RDONLY);
            if(fd == -1){
                errExit("open");
            }
            printf("Opened '%s' on fd %d
    ", argv[j], fd);
    
            ev.events = EPOLLIN;  // Only interested in input events
            ev.data.fd = fd;
            if(epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) == -1)
                errExit("epoll_ctl");
        }
        numOpenFds = argc - 1;
        while(numOpenFds > 0){
            printf("About to epoll_wait()
    ");
            ready = epoll_wait(epfd, evlist, MAX_EVENTS, -1);
            if(ready == -1){
                if(errno == EINTR)
                    continue;
                else
                    errExit("epoll_wait");
            }
            printf("Ready: %d
    ", ready);
            for(j=0;j<ready;j++){
                printf("  fd=%d; events: %s%s%s
    ", evlist[j].data.fd,
                        (evlist[j].events & EPOLLIN) ? "EPOLLIN " : "",
                        (evlist[j].events & EPOLLHUP) ? "EPOLLHUP " : "",
                        (evlist[j].events & EPOLLERR) ? "EPOLLERR " : "");
                if(evlist[j].events & EPOLLIN){
                    s = read(evlist[j].data.fd, buf, MAX_BUF);
                    if(s == -1)
                        errExit("read");
                    printf("    read %d bytes: %.*s
    ", s,s,buf);
                } else if(evlist[j].events & (EPOLLHUP | EPOLLERR)) {
                    printf("    closing fd %d
    ", evlist[j].data.fd);
                    if(close(evlist[j].data.fd)==-1)
                        errExit("close");
                    numOpenFds--;
                }
            }
        }
        printf("All file descriptors closed. bye
    ");
        exit(EXIT_SUCCESS);
    }
    

    from: 《The Linux Programming Interface》P1355

  • 相关阅读:
    【转】微服务架构模式简介
    大话微服务
    Howto: 在ArcGIS10中将地图文档(mxd文档)批量保存到之前版本
    在Google Maps中导出KML文件
    ASP.NET(c#) 日期选择控件的另一种实现方法
    asp.net中的时间日期选择控件
    JAVA实现Excel导入/导出【转】
    将Gridview中的数据出到excel或word中
    asp.net导出excel并弹出保存提示框
    在ASP.NET中将GridView数据导出到Word、Excel
  • 原文地址:https://www.cnblogs.com/wucg/p/8727258.html
Copyright © 2011-2022 走看看