当前位置: 首页 > news >正文

四川长昕建设工程有限公司网站兰州网站哪里做

四川长昕建设工程有限公司网站,兰州网站哪里做,合肥专业商业网站,网站建设开发服务费下什么科目哈喽#xff0c;我是老吴#xff0c;继续记录我的学习心得。一、进步的滞后性我们期望进步是线性#xff1a;每一个人付出一些努力后#xff0c;都希望它有立竿见影的效果。现实是#xff1a;做出努力后#xff0c;结果的显现往往滞后。只有在几个月或几年后#xff0c;… 哈喽我是老吴继续记录我的学习心得。一、进步的滞后性我们期望进步是线性每一个人付出一些努力后都希望它有立竿见影的效果。现实是做出努力后结果的显现往往滞后。只有在几个月或几年后我们才意识到以前学习/工作的真正价值。“失望谷地” 的出现人们在投入数周或数月的辛勤工作后却没有任何看得见的效果于是进入深感沮丧的时期。如何改变1 改变意识。功夫并没有白费它只是蓄积起来了。直到很久以后以前努力的全部价值才会显露出来。2 寻找一些可以帮助自己对抗滞后进步所带来的低落情绪的技巧。例如培养习惯的四大定律具体的如即时奖励、习惯追踪等。二、triggerhappy 源码分析 / 3.select() 的应用正文目录1. thd.c / process_events() 源码分析 2. I/O 多路复用 ( Multiplexing ) 是为了解决什么问题 3. I/O 多路复用设计思路 4. select() 的用法 5. 和 poll/epoll 对比(补充知识非重点) 6. triggerhappythd.c / process_devices() 源码分析 7. 相关参考 写作目的通过阅读 triggerhappy 的源码学习 I/O 多路复用的方法之一 select() 的使用方法。测试环境Ubuntu 16.04Gcc 5.4.01. thd.c / process_events() 源码分析 1.1 process_events() 的作用1) 作用监控 input 设备;读取 input 事件并执行相应的 action;检查 socket 是否有接受到命令。2) 调用流程thd.cmain()start_readers()process_events() 1.2 process_events() 的内容4 个步骤1) 建立主循环while ( count_devices()  0 || cmd_fd ! -1 ) {[...] } 2) 在主循环内使用 select 监测多个 input 设备文件 (重点)while(...) {[...]       // some init for selectretval  select(max_fd1, rfds, NULL, NULL, tv); } 本文的重点就是了解 select 相关的知识点。3) select 返回后调用 process_devices() 读取数据 (重点)while(...) {[...]       // some init for selectretval  select(max_fd1, rfds, NULL, NULL, tv);if (retval) {process_devices();} } process_devices() 是 triggerhappy 的重点函数。先大致了解一下它的作用对于每一个有待读数据的 input 设备文件都调用 read() 函数读取数据然后解析数据根据解析结果去执行相应的 actionaction 在 example.conf 中定义$ cat /etc/triggerhappy/triggers.d/example.conf KEY_VOLUMEUP    1        /usr/bin/amixer set Master 5% ... /usr/bin/amixer set Master 5% 就是一个 action。暂时不用太深入后续会专门写一篇文章来详细分析 process_devices()。4) 是否有接收到用户命令 (th-cmd)while(...) {[...]if (retval) {process_devices();if ( cmd_fd ! -1  FD_ISSET( cmd_fd, rfds ) ) {struct command *cmd  read_command( cmd_fd );obey_command( cmd );free(cmd);}} } cmd_fd 是一个 socketmain()start_readers()cmd_fd  bind_cmdsocket(cmd_file);cmd_fd  socket(AF_UNIX, SOCK_DGRAM, 0); triggerhappy 支持使用 socket 通信以动态增加和删除输入设备例如动态地添加要监测的输入设备 /的 /dev/input/event0$ thd --socket /var/run/triggerhappy.socket $ th-cmd --socket /var/run/triggerhappy.socket --add /dev/input/event0 read_command() 和 obey_command() 负责读取和解析用户通过 socket 发送过来的命令后面找时间写一些关于 domain socket 的文章。接下来我们先学习一下 select 的机制、使用方法和注意事项。注意本文的写作目的不是为了描述 select() 完整的使用方法和内部实现而是在有限的篇幅内尽量整理一下 I/O 多路复用相关的知识点即仅仅是引子更完整的内容仍需要小伙伴自行阅读相关书籍。2. I/O 多路复用 ( Multiplexing ) 是为了解决什么问题: 多文件阻塞 应用通常需要在多个文件描述符上阻塞例如在键盘输入、进程间通信以及其他文件之间协调 I/O。很多情况下一个文件描述符依赖另一个文件描述符。只要是有 1 个文件描述符数据还没有准备好比如发送了 read() 调用但是还没有任何数据就进程会阻塞在此 I/O 操作上此时无法对其他的文件描述符提供服务。这导致应用效率变低影响用户体验。尤其是对于网络应用而言可能会同时打开多个 socket如果应用阻塞在某个 socket上将引发很多问题。设计 I/O 多路复用就是为了解决上述问题支持应用同时在多个文件描述符 (普通文件、管道、套接字...) 上阻塞并在其中某个文件描述符可以读写时收到通知。3. I/O 多路复用设计思路 1 无 I/O 就绪在有可用的文件描述符之前一直处于睡眠状态;2 任意文件描述符 I/O 就绪唤醒应用应用检查是哪个文件描述符可用了;3 执行 I/O 操作应用处理所有 I/O 就绪的文件描述符此时没有阻塞;4 返回第 1 步重新开始;Linux 提供了三种 I/O 多路复用方案-select()、poll() 和 epoll()。本文先将学习重点放在 select() 上同时也稍微了解一下 poll() 和 epoll()明确三者的优缺点。4. select() 的用法 4.1 函数概述$ man 2 select/* According to POSIX.1-2001, POSIX.1-2008 */ #include sys/select.h/* According to earlier standards */ #include sys/time.h #include sys/types.h #include unistd.hint select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); select() 会监测 3 个 文件描述符集直到有 1 个或多个文件描述符集成为就绪态。在给定的文件描述符 I/O 就绪之前并且还没有超出指定的时间限制select() 会阻塞。4.2 参数说明1) 参数 fd_set * readfds、writefds、exceptfdsselect() 监测 3 种 I/O 事件(读、写、异常)每 1 种事件对应 1 个文件描述符集。每个描述符集存储在一个 fd_set 数据类型中可以认为它是一个很大的位数组 (array of bits)select() 中间 3 个文件描述符集参数 readfds、writefds 和 exceptfds 分别对应了我们关心的可读、可写或处于异常条件的文件描述符集。2) 操作文件描述符集的几个宏FD_ZERO从指定集合中删除所有的文件描述符;FD_SET向指定集中添加一个文件描述符而FD_CLR则从指定集中删除一个文件描述符;FD_ISSET检查一个文件描述符是否在给定集合中;由于文件描述符集是静态建立的所以文件描述符数存在上限值而且存在最大文件描述符值这两个值都是由 FD_SETSIZE 设置。在 Linux 中该值是1024;3) 参数 int nfds最大文件描述符 1参数 nfds 必须设为比 3 个文件描述符集合中所包含的最大文件描述符 1 的值。传递该参数是为了让内核不用去检查大于这个值的文件描述符是否属于上述 3 个文件描述符集合这也从侧面说明了 select() 在内核里实现是会遍历 0~nfds 文件描述符。select() 的设计天生就没考虑到用于监测大量文件 I/O 就绪的情景。但是在 triggerhappy 里使用 select() 则是合理的这是因为 一个系统上的 input 设备并不会太多本文末尾还会对 select() 的优缺点进行总结。4) 参数 struct timeval *timeouttimeout NULL永远等待。当所指定的描述符中的之一已就绪或捕捉到一个信号则返回。如果捕捉到一个信号则返回 -1errno 设置为 EINTR。timeout-tv_sec 0 timeout-tv_usec 0完全不等待。测试所有指定的描述符并立即返回。timeout-tv_sec ! 0 || timeout-tv_usec ! 0等待指定的秒数和微秒数。当指定的描述符之一已就绪或超过指定的时间值时立即返回。如果在超时到期时还没有如何描述符准备好则返回 0。4.3 返回说明1) return -1表示有错误发生。典型的错误码 (errno) 包括 EBADF 和 EINTR 等。EBADF: 表示 readfds、writefds、exceptfds 中有非法文件描述符。EINTR: 表示该调用被某个信号中断了。2) return 0表示在有文件描述符成为就绪态之前 select() 已经超时。在这种情况下每个返回的文件描述符集合将被清空。3) return 0表示有 1 个或多个文件描述符已就绪。返回值表示处于就绪态的文件描述符个数。每个集合都修改成只包含相应类型的 I/O 就绪的文件描述符。每个集合都需要检查通过 FD_ISSET() 以此找出发生的 I/O 事件是什么。如果同一个文件描述符在 readfds、writefds 和 exceptfds 中同时被指定且它对于多个 I/O 事件都处于就绪态的话那么就会被统计多次。。例如同一描述符已准备好读和写那么在返回值中会对其计 2 次。4.4 注意事项每次调用 select() 之前都要对所有参数进行初始化;在 Linux 上如果 select() 被信号中断的话struct timeval 会被修改以表示剩余的超时时间;exceptfds 常常被误解为在文件描述符上出现了异常情况这是错误的。它其实与伪终端和流式套接字相关;如果在一个描述符上碰到了文件尾端select() 会认为该描述符是可读的。此时调用 read()会返回 0这是 UNIX 系统指示到达文件尾端的方法。很多人错误地认为当到达文件尾端时 select() 会指示一个异常条件。如果想更详细地了解 I/O 多路复用的使用方法可以学习一下开源软件 libevent。4.5 最简单的 demo 程序1) 初始化select() 的参数#define TIMEOUT 5 #define BUF_LEN 1024int main (void) {struct timeval tv;fd_set readfds;int ret;/* Wait on stdin for input. */FD_ZERO(readfds);FD_SET(STDIN_FILENO, readfds);/* Wait up to five seconds. */tv.tv_sec  TIMEOUT;tv.tv_usec  0;[...] } 2) select () 监测是否有 I/O 就绪int main (void) {[...]   // 1) init select param/* All right, now block! */ret  select (STDIN_FILENO  1, readfds, NULL, NULL, tv);if (ret  -1) {perror (select);return 1;} else if (!ret) {printf (%d seconds elapsed.\n, TIMEOUT);return 0;}[...] } 3) 进行 I/O 操作int main (void) {[...]   // 1) init select param[...]   // 2) do select()// 3) do I/Oif (FD_ISSET(STDIN_FILENO, readfds)) {char buf[BUF_LEN1];int len;len  read (STDIN_FILENO, buf, BUF_LEN);if (len  -1) {perror (read);return 1;}if (len) {buf[len]  \0;printf (read: %s\n, buf);}}return 0; } 4) 运行效果$ gcc simple_select.c -o simple_select $ ./simple_select  a read: a 启动程序时程序会阻塞这时从键盘敲入 a程序会被唤醒。5. 和 poll / epoll 进行简单对比(补充知识非重点) 5.1 对比 poll()$ man 2 poll#include poll.h int poll(struct pollfd *fds, nfds_t nfds, int timeout);struct pollfd {int   fd;         /* file descriptor */short events;     /* requested events */short revents;    /* returned events */ }; poll()系统调用是 System V 的 I/O 多路复用解决方案。它解决了一些select()的不足不过出于习惯或可移植性的考虑select() 还是被频繁使用。poll 的监测对象是 struct pollfd 数组它可以精准的指定要监测的文件集合。而 select() 的文件描述符集合是静态的当文件集合是稀疏的时例如要监测文件描述符 和 1000 时select() 的效率比 poll() 低很多。select() 返回时会重新创建文件描述符集因此每次调用都必须重新初始化。poll() 系统调用会把输入 (events 成员) 和输出 (revents 成员) 分离开无需重新初始化数组就可以重新使用。5.2 对比 epollepoll 是 Linux 特有的 I/O 多路复用解决方案。epoll 的实现比 poll() 和 select() 要复杂得多epoll 解决了前两个都存在的基本性能问题并增加了一些新的特性。poll() 和 select() 每次调用时内核必须遍历所有被监视的文件描述符。当文件描述符列表变得很大时例如包含几百个甚至几千个文件描述符时每次调用都要遍历列表就变成规模上的瓶颈。而 epoll 监测的对象是事件无需遍历文件列表所以在性能上有很大的提升。select、poll、epoll 的后端都是 struct file_operations 里的 unsigned int (*poll) (struct file *, struct poll_table_struct *);。以后有机会的话会继续跟进它们三者在内核里的实现。6. 继续分析 triggerhappythd.c / process_devices()读取 input 数据 static void process_devices(void) {for_each_device( check_device ); } devices.c / for_each_device() 会遍历所有 input 设备(内含 input 文件描述符)对每一个设备都调用 check_device() 函数static void check_device( device *d ) {int fd  d-fd;if (FD_ISSET( fd, rfds )) {if (read_event( d )) {/* read error? Remove the device! */remove_device( d-devname );}} } thd.c / read_event() 执行input 数据的 read 操作static int read_event( device *dev ) {[...]           // some initstruct input_event ev;int n  read( fd, ev, sizeof(ev) );[...]           // parse and do actionrun_triggers( ev.type, ev.code, ev.value, *keystate, dev ); } 1 个input_event 事件相当于产生了一个 trigger,接下来的重点就是调用 trigger.c / run_triggers() 来触发用户自定义的 action 了。鉴于大多数人的注意力无法在一篇文章里上集中太久更多的内容将放在后面的文章里。建议大家可以先自行阅读相关书籍不是自己理解到的东西是消化不了的。7. 相关参考 《UNIX 环境高级编程》141617.6 章节《Linux 系统编程》2.104.28.711.7 章节《Linux/UNIX系统编程手册》63 章节Libevent 推荐阅读    专辑|Linux文章汇总    专辑|程序人生    专辑|C语言嵌入式Linux微信扫描二维码关注我的公众号
http://www.zqtcl.cn/news/551814/

相关文章:

  • 河南建设网站公司简介做新闻类网站需要什么资质
  • 网络文化经营许可证图片下载优化大师安装桌面
  • 网站cms系统教育网站开发文档
  • 用网站做淘客怎么做网站建设在电访销售话术
  • 做电影网站赚了几百万动画制作流程
  • 怎么做企业的网站首页wordpress 主机迁移
  • 网站常见问题网页设计代码开头
  • 聊城网站推广品牌推广计划描述
  • 池州网站制作优化有没有专业做特产的网站
  • wordpress采集站源码wordpress好用的会员插件
  • 寿县城乡建设局网站青岛网站建设大全
  • 杭州做网站的好公司哪家好做影视网站侵权吗
  • 自助建站网站seo公司想学编程做网站
  • 网站空间备案要多久花木公司网站源码
  • 高端求职网站排名ftontpage如何做网站
  • 音乐网站开发技术河南省住房和城乡建设门户网站
  • 吉安微信网站弋阳县建设工程网站
  • 网站建设自学建站视频教程哈尔滨全国网站建设
  • 网站建设基础培训网站架构拓扑图
  • 网站开发价格预算成都必去的地方排行榜
  • 鹤岗做网站企业建立网站主要包括那些流程
  • 如何进网站出口外贸是做什么的
  • 网站制作北京网站建设公司哪家好一个人 建设网站
  • 百度网站是什么阿里云免费网站建设
  • 网站建设平台源码攻击网站步骤
  • 注册了网站之后怎么设计深圳开发app
  • 国外网站搭建平台移动互联网公司
  • 做网络私活的网站网站开发的人
  • 数据分析网站开发四川手机网站设计方案
  • 什么是网络营销的方法莱州网站建设关键字排名优化网络托管微信代运营