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

软件开发外包公司好不好seo站

软件开发外包公司好不好,seo站,个人网页参考,做实验流程图的网站1、select接口简介 1.1 select接口使用用例 select 是操作系统多路 I/O 复用技术实现的方式之一。 select 函数允许程序监视多个文件描述符,等待所监视的一个或者多个文件描述符变为“准备好”的状态。所谓的”准备好“状态是指:文件描述符不再是阻塞状…

1、select接口简介

1.1 select接口使用用例

  select 是操作系统多路 I/O 复用技术实现的方式之一。

  select 函数允许程序监视多个文件描述符,等待所监视的一个或者多个文件描述符变为“准备好”的状态。所谓的”准备好“状态是指:文件描述符不再是阻塞状态,可以用于某类 IO 操作了,包括可读,可写,发生异常三种。

  select 在应用中使用的例子如下段代码所示。

#include <stdio.h>
#include <sys/select.h>int main (int argc, char *argv[])
{fd_set fdset;int ret;struct timeval timeout;char ch;timeout.tv_sec = 10;timeout.tv_usec = 0;for (;;) {FD_ZERO(&fdset);FD_SET(STDIN_FILENO, &fdset);ret = select(STDIN_FILENO + 1, &fdset, NULL, NULL, &timeout);if (ret <= 0) {break;} else if (FD_ISSET(STDIN_FILENO, &fdset)) {read(STDIN_FILENO, &ch, 1);if (ch == '\n') {continue;}fprintf(stdout, "input char: %c\n", ch);if (ch == 'q') {break;}}}return (0);
}

1.2 select函数原型分析

LW_API INT   select(INT                  iWidth, fd_set              *pfdsetRead,fd_set              *pfdsetWrite,fd_set              *pfdsetExcept,struct timeval      *ptmvalTO);
  • iWidth 为设置的文件集中,最大的文件号 + 1;
  • pfdsetRead 为关心的可读文件集;
  • pfdsetWrite 为关心的可写文件集;
  • pfdsetExcept 为关心的异常文件集;
  • ptmvalTO 为等待超时时间,LW_NULL 表示永远等待;
  • 返回值:正常返回等待到的文件数量,错误返回 PX_ERROR。

2、select 实现

2.1 内核中 select 实现

select 函数具体实现如下,主体可以分为 3 个部分:

  • 检查读文件集、写文件集、异常文件集,调用 ioctl 的 FIOSELECT 命令
  • 调用 API_SemaphoreBPend 接口进行阻塞
  • 被唤醒后,调用 ioctl 的 FIOUNSELECT 命令
LW_API  
INT     pselect (INT                     iWidth, fd_set                 *pfdsetRead,fd_set                 *pfdsetWrite,fd_set                 *pfdsetExcept,const struct timespec  *ptmspecTO,const sigset_t         *sigsetMask)
{......if (pfdsetRead) {                                                   /*  检查读文件集                */selwunNode.SELWUN_seltypType = SELREAD;if (__selDoIoctls(&pselctx->SELCTX_fdsetOrigReadFds, pfdsetRead, iWidth, FIOSELECT, &selwunNode, LW_TRUE)) {                      /*  遇到错误,立即退出           */iIsOk = PX_ERROR;}}....../*  开始等待,这里是 select 阻塞的根源。 一般会在驱动的中断处理函数中调用 wakeup_node ,去释放这个二进制信号量   */ulError = API_SemaphoreBPend(pselctx->SELCTX_hSembWakeup,ulWaitTime);                            /*  开始等待                    */if (pfdsetRead) {                                                   /*  检查读文件集                */selwunNode.SELWUN_seltypType = SELREAD;if (__selDoIoctls(&pselctx->SELCTX_fdsetOrigReadFds, pfdsetRead, iWidth, FIOUNSELECT, &selwunNode, LW_FALSE)) {                     /*  如果存在节点,删除节点       */iIsOk = PX_ERROR;}}......
}

  select 操作的一个重要数据结构,就是 “唤醒节点” ——LW_SEL_WAKEUPNODE

  select 函数允许程序监视多个文件描述符,这里的每一个文件描述符,对应一个“唤醒节点”。唤醒节点中一个重要的变量就是 SELWUN_hThreadId 线程 ID,记录了创建该等待节点的线程句柄(其实就是调用 select 接口的线程)。该数据结构通过 ioctl 接口,传递到设备文件描述符对应的设备驱动中,由设备驱动去维护、管理该唤醒节点。

/*********************************************************************************************************等待节点类型
*********************************************************************************************************/typedef enum {SELREAD,                                                            /*  读阻塞                      */SELWRITE,                                                           /*  写阻塞                      */SELEXCEPT                                                           /*  异常阻塞                    */
} LW_SEL_TYPE;/*********************************************************************************************************等待链表节点.
*********************************************************************************************************/typedef struct {LW_LIST_LINE            SELWUN_lineManage;                          /*  管理链表                   */UINT32                  SELWUN_uiFlags;LW_OBJECT_HANDLE        SELWUN_hThreadId;                           /*  创建节点的线程句柄          */INT                     SELWUN_iFd;                                 /*  链接点的文件描述符          */LW_SEL_TYPE             SELWUN_seltypType;                          /*  等待类型                   */
} LW_SEL_WAKEUPNODE;
typedef LW_SEL_WAKEUPNODE  *PLW_SEL_WAKEUPNODE;    

2.2 设备驱动的 ioctl 实现

  SylixOS 的 select 接口实现中,系统会调用到每一个 fd 对应的设备驱动的 ioctl 接口,并会调用到如下表所示的两个命令:

命令说明
FIOSELECT添加 SEL_WAKE_NODE 节点
FIOUNSELECT移除 SEL_WAKE_NODE 节点

  驱动中 ioctl 的 FIOSELECT 实现,通常会调用 SEL_WAKE_NODE_ADD 接口,向设备驱动中添加一个“唤醒节点”(也可以把它理解成“等待节点”)。以 gpio 驱动为例:

static INT  _gpiofdSelect (PLW_GPIOFD_FILE  pgpiofdfil, PLW_SEL_WAKEUPNODE   pselwunNode)
{......SEL_WAKE_NODE_ADD(&pgpiofdfil->GF_selwulist, pselwunNode);......
}static INT  _gpiofdUnselect (PLW_GPIOFD_FILE  pgpiofdfil, PLW_SEL_WAKEUPNODE   pselwunNode)
{......SEL_WAKE_NODE_DELETE(&pgpiofdfil->GF_selwulist, pselwunNode);......
}static INT  _gpiofdIoctl (PLW_GPIOFD_FILE pgpiofdfil, INT             iRequest, LONG            lArg)
{......switch (iRequest) {......case FIOSELECT:pselwunNode = (PLW_SEL_WAKEUPNODE)lArg;return  (_gpiofdSelect(pgpiofdfil, pselwunNode));case FIOUNSELECT:pselwunNode = (PLW_SEL_WAKEUPNODE)lArg;return  (_gpiofdUnselect(pgpiofdfil, pselwunNode));}......
}

节点的组织形式如下:

  • 设备驱动相关结构体中,会维护一个指针,指向唤醒节点链表(这个链表由设备驱动去维护)
  • 链表节点的添加,是调用SEL_WAKE_NODE_ADD 函数完成的

在这里插入图片描述

2.3 阻塞与唤醒实现

阻塞
  select 本身是一个阻塞函数。通过调用二进制信号量 API_SemaphoreBPend,实现阻塞操作。

注意,这里的二进制信号量,实际上是一个同步信号量。在调用 pend 之前,pselect 会首先调用 ioctl,传递 FIOSELECT 参数。此接口中会判断 当前 是否满足 select 的唤醒条件,若满足则先调用 post,以使之后调用的 pend 不会被阻塞; 若 当前 不满足 select 的唤醒条件,则会进入阻塞状态,等待设备驱动主动去唤醒

唤醒
  通常是由 select 所监听的文件描述符集对应的设备驱动去唤醒。还是以 gpio 驱动为例,当一个 gpio 中断(电平触发、边沿触发)产生时,就会告诉操作系统,该 gpio 的状态“可读”,通过调用 SEL_WAKE_UP_ALL 接口实现唤醒操作。该接口底层实现,实际上就是调用 API_SemaphoreBPost

LW_API  
VOID    API_SelWakeup (PLW_SEL_WAKEUPNODE   pselwunNode)
{
....../*  根据唤醒节点中保存的线程 ID,获取线程 TCB 结构  */usIndex = _ObjectGetIndex(pselwunNode->SELWUN_hThreadId);ptcb = __GET_TCB_FROM_INDEX(usIndex);if (!ptcb || !ptcb->TCB_pselctxContext) {                           /*  线程不存在                  */return;}/*  设置唤醒节点的 READY 属性 */LW_SELWUN_SET_READY(pselwunNode);/*  根据 TCB,找到需要唤醒的句柄 SELCTX_hSembWakeup  */pselctxContext = ptcb->TCB_pselctxContext;API_SemaphoreBPost(pselctxContext->SELCTX_hSembWakeup);             /*  提前激活即将等待线程        */
}static irqreturn_t  _gpiofdIsr (PLW_GPIOFD_FILE pgpiofdfil)
{
......SEL_WAKE_UP_ALL(&pgpiofdfil->GF_selwulist, SELREAD);
......
}
http://www.dtcms.com/wzjs/48060.html

相关文章:

  • 精品服装网站建设百度关键词工具
  • 大连网站建设信息拼多多seo是什么意思
  • 网站域名注册要多少钱室内设计培训班学费一般多少
  • 设计本网站怎么样网站优化包括
  • 简易个人博客网站源码爱站网长尾关键词挖掘查询工具
  • ajax 翻页 wordpress搜索引擎优化与推广技术
  • 企业网站管理系统演示平台天津seo推广优化
  • wordpress google cdn gravator如何网站关键词优化
  • 莱芜网站优化招聘网亚洲精华国产精华液的护肤功效
  • 王烨燃大夫简介湖南网站建设推广优化
  • 一个大佬做的本子网站深圳网站建设专业乐云seo
  • 百度竞价推广价格seo超级外链工具
  • 温州网站建设推广百度安装免费下载
  • 1做网站推广关键词排名优化易下拉技巧
  • 网络推广公司怎么报税常熟seo网站优化软件
  • 聚美优品网站建设方案信息流优化师是做什么的
  • 多种手机网站建设互联网运营培训课程
  • 如何做网站图片关键词优化是怎样收费的
  • 小学网站建设方案书搜狗站长平台
  • 杭州科技公司网站建设百度官方官网
  • wordpress做的网站效果6网站设计报价方案
  • 贸易网站建设企业网站分析报告
  • 一页网站首页图如何做怎么自己创建网址
  • wordpress建站插件网络广告营销的特点
  • 手机怎么做网站精美软文句子
  • 新手20种引流推广方法seo在线优化技术
  • 优质校建设专题网站近期时政热点新闻20条
  • 制作一个网站要多少钱郑州技术支持seo
  • 做网站要不要35类商标深圳seo优化推广
  • 公司响应式网站建设平台网站优化排名方法