zoukankan      html  css  js  c++  java
  • Linux 多路复用 select / poll

    多路复用都是在阻塞模式下有效!

    linux中的系统调用函数默认都是阻塞模式,例如应用层读不到驱动层的数据时,就会阻塞等待,直到有数据可读为止。


    问题:在一个进程中,同时打开了两个或者两个以上的文件,读第一个文件时没有数据阻塞了。程序就停止在此位置等待,可是第二个文件有数据可读了,数据读不到怎么办?

    回答:此种问题可以用多路复用 select / poll 完美解决。


    多路复用 select / poll :对多个文件描述符进行监控,一旦有文件描述符可读或者可写,就会通知应用程序进行读写。


    1、select


    // 监控多个文件描述符属性变化,包括可读,可写,出错异常

    // 参数1:监控的最大描述符加1

    // 参数2:监控的可读描述符集合

    // 参数3:监控的可写描述符集合

    // 参数4:监控的出错异常描述符集合

    // 参数5:监控时间 NULL-永远等待 0-不阻塞 固定时间

    int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

    // 检查指定的文件描述符是否可读写

    int FD_ISSET(int fd, fd_set *set);

    // 将一个文件描述符加入到监控集合中

    void FD_SET(int fd, fd_set *set);

    // 将指定文件描述符从集合中删除

    void FD_CLR(int fd, fd_set *set);

    // 清空集合

    void FD_ZERO(fd_set *set);


    2、poll


    struct pollfd {
        int fd;       /* 监控的文件描述符 */
        short events;   /* 等待的事件 */
        short revents;  /* 发生的事件 */
    };

    // 监控多个文件描述符的属性变化

    // 参数1:文件描述符集合

    // 参数2:文件描述符数量

    // 参数3:超时时间

    int poll(struct pollfd *fds, nfds_t nfds, int timeout);

    POLLIN:可读

    POLLOUT:可写

    POLLERR:出错

    ------------------------
    应用:实现一个poll的接口:

    struct pollfd pfd[2];
    
    pfd[0].fd = fd;
    pfd[0].events = POLLIN;
    
    // 0为标准输入
    pfd[1].fd = 0;
    pfd[1].events = POLLIN;
    
    ret = poll(pfd,  2,  -1);
    if(ret > 0)
    {
    	// 查询
    	if(pfd[0].revents & POLLIN)
    		ret = read(fd, &event, sizeof(struct key_event));
    
    	if(pfd[1].revents & POLLIN)
    		fgets(kbd_buf, 64, stdin);
    }

    ------------------------
    驱动:实现一个poll的接口:

    unsigned int key_drv_poll(struct file *filp, struct poll_table_struct *pts)
    {
    	// 如果没有数据返回一个0, 有数据返回一个POLLIN
    	unsigned int mask = 0;
    
    	//将当前的等待队列头,注册到vfs层
    	//参数1--文件对象
    	//参数2--等待队列头
    	//参数3--当前函数第二参数
    	poll_wait(filp, &key_dev->wq_head, pts);
    
    	if(key_dev->have_data)
    		mask |= POLLIN;
    
    	return mask;
    }
  • 相关阅读:
    野心和实力的磨合
    tpm
    菜猫学习linux笔记(1)
    调试理解过程
    TSS学习记录
    RSA加密算法理解(整理自网络)
    *args和**kwargs在python中的作用
    在 Ubuntu 16.04 中安装谷歌 Chrome 浏览器
    ubuntu安装微信客户端
    ubuntu 桌面操作系统安装WPS办公软件的方法
  • 原文地址:https://www.cnblogs.com/lialong1st/p/7756670.html
Copyright © 2011-2022 走看看