多输入select

╰+攻爆jí腚メ 2021-12-21 07:55 244阅读 0赞

目录

  • 多输入select

    • IO模型
    • select介绍
    • 小demo
    • 注意
    • 引入电子书

title: 多输入select
date: 2019/3/20 17:21:34
toc: true
-—

多输入select

IO模型

首先介绍下IO模型,摘录《嵌入式Linux应用程序开发标准教程》

I/O 处理的模型有 5 种。

  • 阻塞 I/O 模型: 在这种模型下,若所调用的 I/O 函数没有完成相关的功能,则会使进程挂起,直到相关数据到达才会返回。对管道设备、终端设备和网络设备进行读写时经常会出现这种情况
  • 非阻塞模型:在这种模型下,当请求的 I/O 操作不能完成时,则不让进程睡眠,而且立即返回。非阻塞 I/O 使用户可以调用不会阻塞的 I/O 操作,如 open()、 write()和 read()。如果该操作不能完成,则会立即返回出错(例如:打不开文件)或者返回 0(例如:在缓冲区中没有数据可以读取或者没有空间可以写入数据)。
  • I/O 多路转接模型:在这种模型下,如果请求的 I/O 操作阻塞,且它不是真正阻塞 I/O,而是让其中的一个函数等待,在这期间, I/O 还能进行其他操作。 select()和 poll 函数()就是属于这种模型。
  • 信号驱动 I/O 模型: 在这种模型下, 通过安装一个信号处理程序, 系统可以自动捕获特定信号的到来,从而启动 I/O。这是由内核通知用户何时可以启动一个 I/O 操作决定的。
  • 异步 I/O 模型:在这种模型下,当一个描述符已准备好,可以启动 I/O 时,进程会通知内核。现在,并不是所有的系统都支持这种模型。

select介绍

更多的可以参考 > http://www.php.cn/linux-370682.html

select()和 poll()的 I/O 多路转接模型是处理 I/O 复用的一个高效的方法。它可以具体设置程序中每一个所关心的文件描述符的条件、希望等待的时间等,从 select()和 poll()函数返回时,内核会通知用户已准备好的文件描述符的数量、已准备好的条件等。通过使用 select()和 poll()函数的返回结果,就可以调用相应的 I/O 处理函数。

mark

mark

小demo

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/time.h>
  4. #include <sys/types.h>
  5. #include <unistd.h>
  6. int
  7. main(void)
  8. {
  9. fd_set rfds;
  10. struct timeval tv;
  11. int retval;
  12. /* Watch stdin (fd 0) to see when it has input. */
  13. FD_ZERO(&rfds);
  14. FD_SET(0, &rfds);
  15. /* Wait up to five seconds. */
  16. tv.tv_sec = 5;
  17. tv.tv_usec = 0;
  18. retval = select(1, &rfds, NULL, NULL, &tv);
  19. /* Don't rely on the value of tv now! */
  20. if (retval == -1)
  21. perror("select()");
  22. else if (retval)
  23. printf("Data is available now.\n");
  24. /* FD_ISSET(0, &rfds) will be true. */
  25. else
  26. printf("No data within five seconds.\n");
  27. exit(EXIT_SUCCESS);
  28. }

注意

当使用 select()函数时,存在一系列的问题,例如:内核必须检查多余的文件描述符,每次调用 select()
之后必须重置被监听的文件描述符集,而且可监听的文件个数受限制(使用 FD_SETSIZE 宏来表示
fd_set 结构能够容纳的文件描述符的最大数目)等。

引入电子书

这里的思路就是使用select监视两个输入,这里两个输入都是非阻塞的,最后监视使用永远阻塞

  1. int AllInputDevicesInit(void)
  2. {
  3. T_InputOp* now=T_InputOp_list;
  4. int iError = -1;
  5. FD_ZERO(&g_fd_set);
  6. while (now)
  7. {
  8. if (0 == now->Init())
  9. {
  10. FD_SET(now->fd, &g_fd_set);
  11. if (g_fd_max < now->fd)
  12. {
  13. g_fd_max = now->fd;
  14. }
  15. iError = 0;
  16. }
  17. now = now->next;
  18. }
  19. g_fd_max+=1;
  20. return iError;
  21. }
  22. int GetInputEvent(T_InputEvent * out)
  23. {
  24. T_InputOp* now=T_InputOp_list;
  25. int ret;
  26. fd_set read_fd_set=g_fd_set;
  27. // timeout=NULL 是永远等待,如果有数据才返回
  28. ret=select(g_fd_max, &read_fd_set, NULL, NULL, NULL);
  29. if(ret>0)
  30. {
  31. while (now)
  32. {
  33. if (FD_ISSET(now->fd, &read_fd_set))
  34. {
  35. if (0 == now->GetInputEventOp(out))
  36. {
  37. return 0;
  38. }
  39. now = now->next;
  40. }
  41. }
  42. }
  43. return -1;
  44. }

转载于:https://www.cnblogs.com/zongzi10010/p/10574367.html

发表评论

表情:
评论列表 (有 0 条评论,244人围观)

还没有评论,来说两句吧...

相关阅读