精华内容
下载资源
问答
  • http://www.cppfans.org/1417.htmlhttp://blog.lucode.net/linux/epoll-tutorial.html现如今,网络通讯中用epoll(linux)和IOCP(windows)几乎大家津津乐道的东西,不为别的,就因为高效,所以大家喜欢用。...

    http://www.cppfans.org/1417.html

    http://blog.lucode.net/linux/epoll-tutorial.html

    现如今,网络通讯中用epoll(linux)和IOCP(windows)几乎是大家津津乐道的东西,不为别的,就因为高效,所以大家喜欢用。IOCP的基础东西已经讲过了,可翻阅《IOCP浅析》 《IOCP浅析[二]——IOCP出现的意义和函数接口》.

    epoll是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率,因为它会复用文件描述符集 合来传递结果而不用迫使开发者每次等待事件之前都必须重新准备要被侦听的文件描述符集合,另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符 集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。epoll除了提供select/poll那种IO事件的电平触发 (Level Triggered)外,还提供了边沿触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,减少epoll_wait/epoll_pwait的调用,提高应用程序效率。Linux2.6内核中对/dev/epoll设备的访问的封装(system epoll)。

    这个使我们开发网络应用程序更加简单,并且更加高效。

    为什么要使用epoll?

    同样,我们在linux系统下,影响效率的依然是I/O操作,linux提供给我们select/poll/epoll等多路复用I/O方式(kqueue暂时没研究过),为什么我们对epoll情有独钟呢?原因如下:

    1.文件描述符数量的对比。

    epoll并没有fd(文件描述符)的上限,它只跟系统内存有关,我的2G的ubuntu下查看是20480个,轻松支持20W个fd。可使用如下命令查看:

    cat /proc/sys/fs/file-max

    再来看select/poll,有一个限定的fd的数量,linux/posix_types.h头文件中

    #define __FD_SETSIZE    1024

    2.效率对比。

    当然了,你可以修改上述值,然后重新编译内核,然后再次写代码,这也是没问题的,不过我先说说select/poll的机制,估计你马上会作废上面修改枚举值的想法。

    select/poll会因为监听fd的数量而导致效率低下,因为它是轮询所有fd,有数据就处理,没数据就跳过,所以fd的数量会降低效率;而epoll只处理就绪的fd,它有一个就绪设备的队列,每次只轮询该队列的数据,然后进行处理。(先简单讲一下,第二篇还会详细讲解)

    3.内存处理方式对比。

    不管是哪种I/O机制,都无法避免fd在操作过程中拷贝的问题,而epoll使用了mmap(是指文件/对象的内存映射,被映射到多个内存页上),所以同一块内存就可以避免这个问题。

    btw:TCP/IP协议栈使用内存池管理sk_buff结构,你还可以通过修改内存池pool的大小,毕竟linux支持各种微调内核。

    epoll的工作方式

    epoll分为两种工作方式LT和ET。

    LT(level triggered) 是默认/缺省的工作方式,同时支持 block和no_block socket。这种工作方式下,内核会通知你一个fd是否就绪,然后才可以对这个就绪的fd进行I/O操作。就算你没有任何操作,系统还是会继续提示fd已经就绪,不过这种工作方式出错会比较小,传统的select/poll就是这种工作方式的代表。

    ET(edge-triggered) 是高速工作方式,仅支持no_block socket,这种工作方式下,当fd从未就绪变为就绪时,内核会通知fd已经就绪,并且内核认为你知道该fd已经就绪,不会再次通知了,除非因为某些操作导致fd就绪状态发生变化。如果一直不对这个fd进行I/O操作,导致fd变为未就绪时,内核同样不会发送更多的通知,因为only once。所以这种方式下,出错率比较高,需要增加一些检测程序。

    LT可以理解为水平触发,只要有数据可以读,不管怎样都会通知。而ET为边缘触发,只有状态发生变化时才会通知,可以理解为电平变化。

    如何使用epoll?

    使用epoll很简单,只需要

    #include

    有三个关键函数:

    int epoll_create(int size);

    int epoll_ctl(int epfd, int op, int fd, struct epoll_events* event);

    int epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout);

    当然了,不要忘记关闭函数.

    ============分割线==============

    这篇就讲到这里了,下面两篇主要是函数介绍,效率分析,例子。

    前一篇大致讲了一下epoll是个什么东西,优点等内容,这篇延续上一篇的内容,主要是分析epoll的函数,epoll高性能的深入分析。

    epoll的三大函数

    1.创建epoll fd函数

    int epoll_create(int size);

    epoll_create()创建一个epoll的事例,通知内核需要监听size个fd。size指的并不是最大的后备存储设备,而是衡量内核内部结构大小的一个提示。当创建成功后,会占用一个fd,所以记得在使用完之后调用close(),否则fd可能会被耗尽。

    Note:自从Linux2.6.8版本以后,size值其实是没什么用的,不过要大于0,因为内核可以动态的分配大小,所以不需要size这个提示了。

    创建还有另外一个函数

    int epoll_create1(int flag);

    这个函数是在linux 2.6.27中加入的,当你在看陈硕的muduo时可以看到这个函数,其实它和epoll_create差不多,不同的是epoll_create1函数的参数是flag,当flag是0时,表示和epoll_create函数完全一样,不需要size的提示了。

    当flag = EPOLL_CLOEXEC,创建的epfd会设置FD_CLOEXEC

    当flag = EPOLL_NONBLOCK,创建的epfd会设置为非阻塞

    一般用法都是使用EPOLL_CLOEXEC.

    Note:关于FD_CLOEXEC,现在网上好多都说的有点问题,我翻阅了一些资料,请教了一些人,大约明白它的意思了。

    它是fd的一个标识说明,用来设置文件close-on-exec状态的。当close-on-exec状态为0时,调用exec时,fd不会被关闭;状态非零时则会被关闭,这样做可以防止fd泄露给执行exec后的进程。关于exec的用法,大家可以去自己查阅下,或者直接man exec。

    2.epoll事件的注册函数

    int epoll_ctl(int epfd, int op, int fd, struct epoll_event* event);

    select是在监听时告诉内核要监听的事件,而epoll_ctl是先注册需要监听的事件。

    第一个参数epfd,为epoll_create返回的的epoll fd。

    第二个参数op表示操作值。有三个操作类型,

    EPOLL_CTL_ADD  // 注册目标fd到epfd中,同时关联内部event到fd上

    EPOLL_CTL_MOD // 修改已经注册到fd的监听事件

    EPOLL_CTL_DEL // 从epfd中删除/移除已注册的fd,event可以被忽略,也可以为NULL

    第三个参数fd表示需要监听的fd。

    第四个参数event表示需要监听的事件。

    typedef union epoll_data {

    void        *ptr;

    int          fd;

    uint32_t     u32;

    uint64_t     u64;

    } epoll_data_t;

    struct epoll_event {

    uint32_t     events;      /* Epoll events */

    epoll_data_t data;        /* User data variable */

    };

    event参数是一个枚举的集合,可以用” | “来增加事件类型,枚举如下:

    EPOLLIN:表示关联的fd可以进行读操作了。

    EPOLLOUT:表示关联的fd可以进行写操作了。

    EPOLLRDHUP(since Linux 2.6.17):表示套接字关闭了连接,或者关闭了正写一半的连接。

    EPOLLPRI:表示关联的fd有紧急优先事件可以进行读操作了。

    EPOLLERR:表示关联的fd发生了错误,epoll_wait会一直等待这个事件,所以一般没必要设置这个属性。

    EPOLLHUP:表示关联的fd挂起了,epoll_wait会一直等待这个事件,所以一般没必要设置这个属性。

    EPOLLET:设置关联的fd为ET的工作方式,epoll的默认工作方式是LT。

    EPOLLONESHOT (since Linux 2.6.2):设置关联的fd为one-shot的工作方式。表示只监听一次事件,如果要再次监听,需要把socket放入到epoll队列中。

    3.epoll等待事件函数

    int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

    int epoll_pwait(int epfd, struct epoll_event *events, int maxevents, int timeout,  const sigset_t *sigmask);

    上面两个函数的参数含义:

    第一个参数:表示epoll_wait等待epfd上的事件

    第二个参数:events指针携带有epoll_data_t数据

    第三个参数:maxevents告诉内核events有多大,该值必须大于0

    第四个参数:timeout表示超时时间(单位:毫秒)

    epoll_pwait(since linux 2.6.19)允许一个应用程序安全的等待,直到fd设备准备就绪,或者捕获到一个信号量。其中sigmask表示要捕获的信号量。

    函数如果等待成功,则返回fd的数字;0表示等待fd超时,其他错误号请查看errno

    函数到这里就讲完了,下一篇会写一个例子给大家看下这些函数是如何使用的。

    ============

    epoll支持水平触发和边缘触发,理论上来说边缘触发性能更高,但是使用更加复杂,因为任何意外的丢失事件都会造成请求处理错误。Nginx就使用了epoll的边缘触发模型。

    这里提一下水平触发和边缘触发就绪通知的区别,这两个词来源于计算机硬件设计。它们的区别是只要句柄满足某种状态,水平触发就会发出通知;而只有当句柄状态改变时,边缘触发才会发出通知。例如一个socket经过长时间等待后接收到一段100k的数据,两种触发方式都会向程序发出就绪通知。假设程序从这个socket中读取了50k数据,并再次调用监听函数,水平触发依然会发出就绪通知,而边缘触发会因为socket“有数据可读”这个状态没有发生变化而不发出通知且陷入长时间的等待。

    因此在使用边缘触发的 api 时,要注意每次都要读到 socket返回 EWOULDBLOCK为止。 否则netstat 的recv-q会持续增加

    ===============

    通常来说,et方式是比较危险的方式,如果要使用et方式,那么,应用程序应该 1、将socket设置为non-blocking方式 2、epoll_wait收到event后,read或write需要读到没有数据为止,write需要写到没有数据为止(对于non-blocking socket来说,EAGAIN通常是无数据可读,无数据可写的返回状态);

    我们最近遇到一个问题,就是由于在使用epoll的过程中,缓冲区的数据没有读完,造成后续的通信失败。

    表现现象就是,使用netstat -an观察时,这个socket的recv-q值不为0.

    展开全文
  • 展开全部一、触发的定义我们给示波器的...二、触发的原理触发是如何进行的?我们通过对过程的模拟,来看一下触发与未触发时的区别:A、示波器在没有触发的时候,会随机抓取一段时间的信号并生成图像,由于信号是连续...

    展开全部

    一、触发的定义

    我们给示波器的触发下一个明确的定义:

    只有满足62616964757a686964616fe59b9ee7ad9431333431373236一个预设的条件,示波器才会捕获一条波形,这个根据条件捕获波形的动作就是触发。

    二、触发的原理

    触发是如何进行的?我们通过对过程的模拟,来看一下触发与未触发时的区别:

    A、示波器在没有触发的时候,会随机抓取一段时间的信号并生成图像,由于信号是连续不断的,随机抓取的位置并无规律,这些静态的图像逐个显示,就像放胶片电影一样,组合在一起就形成了动态的显示,最终在屏幕上的效果就是看到来回滚动的波形。

    (未触发时)示波器显示画面如下

    麦科信示波器

    B、我们设定一个条件,用一个直流电平作为参考,当信号的电压大于直流电平的一瞬间作为抓取信号的起始点。如下图所示,红色细线就是参考的直流电平,由于每次抓取图像的位置是有规律的,都是在信号过直流电平的瞬间抓取,所以每次抓取的信号相位一样,连续显示的时候完全重叠,看上去就是一条稳定的波形。

    (触发时)示波器显示画面如下

    麦科信示波器

    三、触发的作用

    触发的作用可以总结为两点:

    1、稳定的显示一个周期性的信号,也可以说是同步波形;

    2、从快速而又复杂的信号中抓取想要观察的片段。

    稳定显示一个周期信号在第二节已有演示,如何抓取特定的片段在文末有一个实例,能够帮助我们快速掌握触发的使用方法。

    四、了解几种触发模式

    什么是示波器的触发模式?

    我们知道示波器需要通过触发这样一种办法来使得示波器的扫描与被观测信号同步,从而显示稳定的波形,所谓的触发模式就是指一些为产生触发所选定的方式,以满足不同的观测效果,示波器的基础触发模式有三种:

    自动模式与正常模式

    在自动模式下,示波器首先按照触发条件进行触发,当超过设定的时间没有触发条件时,示波器将强制触发,显示信号。当我们对一个信号的特征不了解时,就应该选用“自动模式”,这种模式可以保证在其他触发设置都不正确时示波器也会有波形显示,尽管波形不一定是稳定的,但是可以为我们进一步调节示波器提供直观的判断。

    正常模式与自动模式不同,正常模式下,示波器只有当触发条件满足时才产生扫描,如果没有触发就不进行扫描,屏幕上什么都没有,正常模式的作用在于观测波形的细节,特别是对于比较复杂的信号,当我们对一个特定的信号设置了特定的触发条件,尤其是满足触发条件的时间间隔比较长时,就应该选用正常模式。

    下图是方波信号未触发时在两种模式下示波器屏幕上的显示情况:

    麦科信示波器

    单次模式

    单次模式也称单序列触发,英文简称“SEQ”,这种模式和正常模式有点类似,就是只有当触发条件满足时才产生扫描,否则不扫描。而不同之处在于,这种扫描一旦完成,示波器的扫描系统就会进入一种休止状态,即后面再有满足触发条件的信号出现也不再进行扫描,必须通过手动的方法,才能进行下一次的触发动作。单次触发模式常用于捕捉单次或多次出现但不具有周期性的信号,比如说一个电路上电时产生的上电信号只会出现一次,如果不使用单次触发,很难捕获到这个信号。

    在实际使用过程中,不同触发模式的选择要依据被观测信号特性和想要观测的内容做出判断,并没有固定的规则,而往往是一个交互的过程,即:选择不同的触发模式来了解信号的特性,又根据信号的特性和想要观测的内容选择有效的触发方式。

    五、常用的触发调节

    触发的核心在于如何设定条件,这是示波器使用中最重要的地方,也是许多用户认为最难掌握的地方,我们来认识一下常用的触发调节:

    触发源

    要使屏幕显示稳定的波形,则需将被测信号本身或者与被测信号有一定时间关系的信号加到触发电路,作为触发条件的比较对象,这个比较的对象就是触发源。

    最常见的触发源是内触发(INT),即用被测信号作为触发源,如通道1、通道2、通道3,使用时需要注意的是选择信号当前所在通道作为触发源,这是大部分初学者忽视的问题:将一个没有接入信号的通道作为触发源。

    麦科信示波器

    除了内触发(INT)外,还有外触发(EXT或AUX IN)和电源触发(LINE)两种触发源。外部触发是独立于信号通道的触发源,该触发源只能是低频与高频信号,与被测信号之间要具有周期性的关系;电源触发使用示波器的市电输入作为触发信号,这种方法在测量与交流电源频率有关的信号时是有效的,感兴趣的朋友可以自行了解下。

    触发电平和触发极性

    触发电平在示波器显示中为一个电压值,单位是“mV”和“V”,另外在界面上都会有一个触发电平线以指示其相对于信号波形的位置,平板示波器的触发电平调节非常简单,通过手指触摸“Level”上线移动即可。

    触发电平调节又叫同步调节,它使得扫描与被测信号同步。只有触发电平在信号幅度的范围之内时,信号才可能被触发。

    触发极性的开关用来选择触发信号的极性。选择正的时候,在信号增加的方向上,当触发信号超过触发电平时就产生触发。选择负的时候,在信号减少的方向上,当触发信号超过触发电平时就产生触发。

    触发极性和触发电平共同决定触发信号的触发点,所用的触发方式在此点上被关注。

    六、触发类型

    用作触发条件的形式有很多,常见的触发类型有:边沿触发、脉宽触发、逻辑触发、N边沿触发、欠幅触发、斜率触发、超时触发、视频触发、串行总线触发等等。

    我们将以边沿触发、脉宽触发和逻辑触发为典型,逐一进行介绍:

    边沿触发:

    边沿触发是最常用最简单也是最有效的触发方式,90%以上的应用都可以只用边沿触发来进行,它是通过查找波形上特定的沿(上升沿或下降沿)来触发信号。

    下图是边沿触发的原理示意:

    以触发电平作为参考,当信号从低于触发电平变化到高于触发电平时产生的触发,就是上升沿触发,反之就是下降沿触发。

    现在给示波器端口输入一个简单的正弦波信号,分别设置为上升沿触发和下降沿触发,我们来观察触发位置的变化(顶部中心位置字母“T”表示触发位置)

    麦科信示波器

    脉宽触发:

    根据信号的脉冲宽度产生的触发简称脉宽触发,脉宽的范围定义可以是小于、大于、等于和不等于,根据极性可分为正脉宽和负脉宽。

    麦科信示波器

    正脉宽:从上升沿与触发电平相交点到相邻的下降沿与触发电平的相交点,两点之间的时间差;

    负脉宽:从下降沿与触发电平相交点到相邻的上升沿与触发电平的相交点,两点之间的时间差。

    现在输入频率为1KHz,即周期为1ms的一个方波信号,使用脉宽触发进行的设置方法如下:

    麦科信示波器

    逻辑触发:

    逻辑触发需要设定每个通道的逻辑值,并设置通道之间的逻辑关系(与、或、非等等),当满足该逻辑关系,并达到设定的时间条件之后,任一通道的边沿变化时,就产生触发。

    每个通道的逻辑值可以设置为:高(大于触发电平时为高)、低(于触发电平时为低)、无(无关)。

    下图中,我们设定CH1为高时触发,CH2为低时触发,当同时满足这两个条件时,就能获取稳定的波形。

    麦科信示波器

    欠幅触发:

    同过设置高低电平门限,触发那些跨过了一个电平门限但没有跨过另一个电平门限的脉冲。有两种类型可选:正矮脉冲,负矮脉冲。

    麦科信示波器

    斜率触发:

    斜率触发是指当波形从一个电平到达另一个电平的时间符合设定的时间条件时,产生触发。

    正斜率时间:波形从低电平达到高电平所用的时间。

    负斜率时间:波形从高电平达到低电平所用的时间。

    麦科信示波器

    超时触发:

    超时触发是指从信号与触发电平交汇处开始,触发电平之上(或之下)持续的时间超过设定的时间时,产生触发。

    视频触发:

    专门针对视频信号的触发方式,根据视频的制式不同而有所不同,一般有PAL/625、SECAM、NTSC/525、720P、1080I和1080P等制式。视频触发在不同的电压档位都可以触发,可以根据需要调整合适的电压档位观察波形。

    麦科信示波器

    串行总线触发

    常见的有I2C、SPI、CAN、LIN、UART等,需要的朋友可行了解或阅读TO1000系列示波器用户手册。

    麦科信示波器

    七、触发耦合+触发抑制

    如何在触发设置中让波形完美呈现?有一些小细节的作用不可忽视,灵活掌握后,对示波器的使用大有裨益。

    触发耦合

    在常用的设置中,一般设定了触发类型、触发电平,波形就能稳定显示了。但对于噪声比较大的信号,噪声的的存在干扰了信号的准确触发,触发耦合的作用就是用来抑制触发电路中的干扰和噪声。

    麦科信示波器

    下面介绍一下常见的耦合方式:

    直流(DC)耦合:触发源信号交流和直流成分都被送入触发电路。

    交流(AC)耦合:触发源信号直流成分被滤去。适用于观察从低频到较高频率的信号。

    高频(HF)抑制:触发源信号中特定频率以上的信号都被滤去。适用于观察含有高频干扰的信号。

    低频(LF)抑制:触发源信号中特定频率以下的信号都被滤去。适用于观察含有低频干扰的信号。

    噪声(Noise)抑制:用低灵敏度的直流耦合来抑制触发源信号中的噪声成分。适用于观察含有高频噪声干扰的信号。

    触发耦合其实就是一种对触发信号的低通或高通滤波。因此可对噪声大的信号加入“高频抑制”耦合,过滤掉其中高频部分,

    触发抑制

    在触发设置中,触发抑制的功能一般会被人忽略。按照定义,抑制是定义两次触发之间的最少时间间隔。当示波器触发一次后,会进入触发释抑时间计数,在此时间内触发功能会被抑制,即使信号满足触发条件,系统也不会标记为触发点。

    触发抑制时间的设置对偶发性多边沿的信号捕获极为好用,使得原来图像不稳定的波形马上清晰。若触发释抑时间没有设置好,示波器将会把不同边沿的信号作为触发点,导致不一致的波形重叠在一起,造成波形显示不稳定。

    触发是目的性很强的操作,也就是说需知道信号异常,才会知道要设定怎样的触发条件。那如何快速发现异常,这应该是设置合理触发的前提,TO1000系列平板示波器拥有最高11万次每秒的波形捕获率,长达28Mpts的存储深度和丰富的触发类型,可以帮助我们在复杂多变的信号中快速定位异常部分。

    捕捉异常信号实例:

    第一步:通过电路故障怀疑信号中可能存在小概率的异常事件;

    第二步:打开示波器高刷新模式,观察到一个高电平的偶发信号;

    麦科信示波器

    第三步:根据异常信号的特性,选择最为合适的边沿触发,调整触发电平直至稳定异常信号。

    麦科信示波器

    展开全文
  • epoll(kqueue),支持两种事件触发模式。水平触发以及边缘触发。epoll实际可以监听多种描述符,下文主要以套接字介绍,并且假设同时注册了读/写。水平触发:只要套接字可读/可写epollwait都会将描述符返回。即只要套...

    epoll(kqueue),支持两种事件触发模式。水平触发以及边缘触发。

    epoll实际可以监听多种描述符,下文主要以套接字介绍,并且假设同时注册了读/写。水平触发:只要套接字可读/可写epollwait都会将描述符返回。即只要套接字的接收缓冲中尚有数据或发送缓冲有空间容纳要发送的数据。这个套接字都会被epoll_wait返回。

    边缘触发:当套接字的缓冲状态发生变化时返回。对于读缓冲,有新到达的数据被添加到读缓冲时触发。对于写缓冲,当缓冲发生容量变更的时候触发(对端确认分组,内核删除已经确认的分组,空出空间,写缓冲容量发生变更)。

    对于边缘触发,很多人,包括我自己,一个开始对边缘这个定义并不是太清楚。例如对于读缓冲,一直以为边缘的意思是,缓冲从空到有数据。也就是以为只有当读缓冲从空到第一次接到数据的时候才会触发一次,如果不把数据读空,那么后续数据到达时不会再次触发。对于写缓冲,我之前的理解是当缓冲从满到有空闲空间时触发。

    下面是linux内核中对epoll readylist的处理介绍。

    fs/eventpoll.c

    判断一个tcp套接字上是否有激活事件:net/ipv4/tcp.c:tcp_poll函数

    epoll_wait返回readylist中的fd。eventpoll.rdllist

    epitem是与epollfd关联的.如果一个fd被加入到多个epollfd中每个epollfd都会为它创建一个epitem。

    下面看下readylist是如何返回到用户空间的。

    epoll_wait通过ep_send_events把fd返回到用户空间。ep_send_events调用ep_scan_ready_list,ep_scan_ready_list调用ep_send_events_proc。在ep_send_events_proc里,将readylist中的epitem一一出列,如果其上确实有用户关注的事件激活,将其添加到用户空间传入的数组中。添加完之后,如果epitem非EPOLLONESHOT,非EPOLLET,会重新将epitem添加回readylist中。供下次epoll_wait时处理。对于EPOLLONESHOT,关注事件将被全部清空,需要用户重新注册事件。

    可见,对于水平触发且没有设置的EPOLLONESHOT fd,epoll_wait返回之前会将fd重新添加到readylist中。如果一个fd只注册了in事件,并在epoll_wait返回之后将这个fd的读缓冲读空(假设读空之后再没有后续数据到来)。这个fd也会一直保存在readylist中,直到下一次调用epoll_wait发现它没有激活的关注事件从readylist中移除。

    下面看下epitem在哪几种情况下会被主动加入readylist。EPOLL_ADD:在ep_insert中处理,如果fd上有关注的事件激活,将epitem加入readylist

    EPOLL_MOD:在ep_modify中处理,如果fd上有关注的事件激活,将epitem加入readylist

    ep_poll_callback:fd有事件到达,如果到达事件是被关注的事件,将epitem加入readylist

    实际上,在linux下,如果用边缘触发同时注册了读和写,当读触发的时候,内核向用户返回fd的时候同时会检查fd是否符合可写的条件(有空间容纳待写入的数据),如果满足可写的条件,同时会加上EPOLLOUT标记。在这一点上,mac 下 kqueue的实现更符合边缘触发的描述。

    边缘触发可能造成饥饿

    边缘模式在什么情况下可能会造成饥饿。我们考虑一个应用,从外来连接接收数据,然后对数据进行处理。如果用边缘触发处理,对一个套接字就需要循环读取,直到没有数据可读为止(通过返回EAGIN,实际上如果读取的数据小于提供的缓冲大小也可以做这样的断定)。如果其中一个连接源源不断的发送数据,这个套接口的读循环就无法退出,导致其它连接没有机会被处理。

    为了避免这种情况的出现,epoll_wait返回时,并不直接处理套接字,而是将套接字添加到active list中。等到把epoll_wait返回的套接字都添加完后,再对active list中的套接字执行io处理。

    对于active list中的每个元素,如果判定套接字不可读,则从active list中移除。否则最多执行有限次操作,超过次数之后将套接字保留在active list中,处理后续套接字。

    伪代码如下:

    func do(fd) {

    //最多recv 10次for i = 0; 10; i ++{

    err,data = recv(fd)

    if err {

    //无数据可读了fd.readable = false

    return

    } else {

    process(data)

    }

    }

    }

    for {

    waitTime = activeList.len() == 0 ? 1000 : 0

    fds = epoll_wait(waitTime)

    for fd in fds {

    activeList.Add(fd)

    }

    for fd in activeList {

    do(fd)

    if !fd.readable {

    activeList.Remove(fd)

    }

    }

    }

    边缘触发模式是否比水平触发模式更高效

    对于这个问题,我实际测试过两种模式,并没有发现肉眼可见的效率差异。

    两种模式执行epoll_wait的次数是大致相当的,区别是readylist大小会有所不同,

    对于只从套接字接收数据而不发送数据的应用来说。考虑以下处理模式:

    每次对一个fd只执行一read,然后处理接收到的数据。

    如果每次调用epoll_wait前,所有fd都会接收到数据,那么无论哪种触发模式,readylist都是所有被监听的fd。开销完全一样。

    边缘触发只有在下述情形下才能获得优势:

    假如有X个连接,套接字接收缓冲为N,对端每次发送都能将N填满,read时提供的用户缓冲为N/M。且发送端的发送频率是接收端处理频率的1/N/M,即读端正好消费完N字节后写端菜继续发送。 在这种模式下水平模式每一轮epoll_wait的readylist都是X。而边缘模式则以N/M为周期,除了周期第一次为X,后续都是N/M-1次0(因为无外来数据到达,不会被添加到readylist中)。

    下面再看下发送的情况。对于out事件,水平触发返回的条件是发送缓冲有空间,边缘触发的条件是发送缓冲容量变更(对端确认数据包,发送端释放发送缓冲中的空间)。

    对于水平触发模式out事件必须按需注册。主要的注册方式有以下两种:上层调用send,将数据添加到应用层的发送缓冲,如果当前没有注册out则注册out,当epoll通知out激活时,发送应用缓冲中的数据,如果数据发送完毕注销out。

    上层调用send,直接发送,如果数据未发送完或返回EAGAIN,则注册out,当epoll通知out激活时,继续发送未发送完成的数据,如果数据发送完毕注销out。

    上述的添加和注销out都是通过epoll_ctl完成。边缘触发模式则无此需要。

    我这里主要分析第二种模式。

    假如发送每次均能将数据全部发完。那么out的注册和注销都不会发生。

    如果接收方慢导致每次均无法将数据全部发送完,那么out将只会注册一次,注销不会发生。因为上层的send会导致待发送队列无法排空。

    导致out的注册和注销频繁发生的情况只有一种,发送端每次send请求发送M字节,但实际只能发送M/N字节,因此注册out,每次out触发后都能发送M/N字节,直到M字节全部发送完毕注销out。在这种情况下,在所有有M字节发送完毕前上层不会触发新的send请求。对于这种情况无论哪种模式每次调用epoll_wait,readylist大小都是一样的。开销的差距只会体现在用epoll_ctl注册和注销out上。

    因此,边缘触发在机制上应该是更高效的,但是构造出一个能明显看出效率优势的场景并不容易。

    下面贴一下我的一个多线程边缘触发模式的实验网络库,支持linux epoll和mac kqueue。区别于muduo的loop per thread模式。这个实验库只启动一个线程监听epoll/kqueue。当套接字被激活后将其交给io线程执行实际的io。sniperHW/hwnet​github.com

    展开全文
  • 前言:在使用示波器进行测量时,首先就是需要掌握选择何种触发方式来捕获特定的事件,所以充分...二、触发的原理触发是如何进行的?我们通过对过程的模拟,来看一下触发与未触发时的区别:A、示波器在没有触发的时...

    4dcde10e42e58acb1effee9027b6be12.png

    前言:在使用示波器进行测量时,首先就是需要掌握选择何种触发方式来捕获特定的事件,所以充分理解触发的概念、原理以及设置方法是有效使用示波器的前提。

    一、触发的定义

    在文章的开始,我们给示波器的触发下一个明确的定义:

    只有满足一个预设的条件,示波器才会捕获一条波形,这个根据条件捕获波形的动作就是触发。

    二、触发的原理

    触发是如何进行的?我们通过对过程的模拟,来看一下触发与未触发时的区别:

    A、示波器在没有触发的时候,会随机抓取一段时间的信号并生成图像,由于信号是连续不断的,随机抓取的位置并无规律,这些静态的图像逐个显示,就像放胶片电影一样,组合在一起就形成了动态的显示,最终在屏幕上的效果就是看到来回滚动的波形。

    07b0ef6b3fa6996f5a9c2477b107b0f3.png

    b1f80c72d2d41753824593b3acb723c2.gif
    (未触发时)示波器显示画面如下


    B、我们设定一个条件,用一个直流电平作为参考,当信号的电压大于直流电平的一瞬间作为抓取信号的起始点。如下图所示,红色细线就是参考的直流电平,由于每次抓取图像的位置是有规律的,都是在信号过直流电平的瞬间抓取,所以每次抓取的信号相位一样,连续显示的时候完全重叠,看上去就是一条稳定的波形。

    d7d507e6736365a29efec40a1748c7ff.png

    (触发时)示波器显示画面如下

    fc5281fa501e15ac895b8b993a2ff395.gif

    三、触发的作用

    触发的作用可以总结为两点:

    1、稳定的显示一个周期性的信号,也可以说是同步波形;

    2、从快速而又复杂的信号中抓取想要观察的片段。

    稳定显示一个周期信号在第二节已有演示,如何抓取特定的片段在文末有一个实例,能够帮助我们快速掌握触发的使用方法。

    四、了解几种触发模式

    什么是示波器的触发模式?

    我们知道示波器需要通过触发这样一种办法来使得示波器的扫描与被观测信号同步,从而显示稳定的波形,所谓的触发模式就是指一些为产生触发所选定的方式,以满足不同的观测效果,示波器的基础触发模式有三种:

    自动模式正常模式

    在自动模式下,示波器首先按照触发条件进行触发,当超过设定的时间没有触发条件时,示波器将强制触发,显示信号。当我们对一个信号的特征不了解时,就应该选用“自动模式”,这种模式可以保证在其他触发设置都不正确时示波器也会有波形显示,尽管波形不一定是稳定的,但是可以为我们进一步调节示波器提供直观的判断。

    正常模式与自动模式不同,正常模式下,示波器只有当触发条件满足时才产生扫描,如果没有触发就不进行扫描,屏幕上什么都没有,正常模式的作用在于观测波形的细节,特别是对于比较复杂的信号,当我们对一个特定的信号设置了特定的触发条件,尤其是满足触发条件的时间间隔比较长时,就应该选用正常模式。

    下图是方波信号未触发时在两种模式下示波器屏幕上的显示情况:

    14d21188750c696e03a8641f57d21f27.gif

    单次模式

    单次模式也称单序列触发,英文简称“SEQ”,这种模式和正常模式有点类似,就是只有当触发条件满足时才产生扫描,否则不扫描。而不同之处在于,这种扫描一旦完成,示波器的扫描系统就会进入一种休止状态,即后面再有满足触发条件的信号出现也不再进行扫描,必须通过手动的方法,才能进行下一次的触发动作。单次触发模式常用于捕捉单次或多次出现但不具有周期性的信号,比如说一个电路上电时产生的上电信号只会出现一次,如果不使用单次触发,很难捕获到这个信号。

    在实际使用过程中,不同触发模式的选择要依据被观测信号特性和想要观测的内容做出判断,并没有固定的规则,而往往是一个交互的过程,即:选择不同的触发模式来了解信号的特性,又根据信号的特性和想要观测的内容选择有效的触发方式。

    五、常用的触发调节

    触发的核心在于如何设定条件,这是示波器使用中最重要的地方,也是许多用户认为最难掌握的地方,我们来认识一下常用的触发调节:

    触发源

    要使屏幕显示稳定的波形,则需将被测信号本身或者与被测信号有一定时间关系的信号加到触发电路,作为触发条件的比较对象,这个比较的对象就是触发源。

    最常见的触发源是内触发(INT),即用被测信号作为触发源,如通道1、通道2、通道3,使用时需要注意的是选择信号当前所在通道作为触发源,这是大部分初学者忽视的问题:将一个没有接入信号的通道作为触发源。

    5944339091b2af7faf0d5e9bd8721a8b.gif

    除了内触发(INT)外,还有外触发(EXT或AUX IN)电源触发(LINE)两种触发源。外部触发是独立于信号通道的触发源,该触发源只能是低频与高频信号,与被测信号之间要具有周期性的关系;电源触发使用示波器的市电输入作为触发信号,这种方法在测量与交流电源频率有关的信号时是有效的,感兴趣的朋友可以自行了解下。

    触发电平触发极性

    触发电平在示波器显示中为一个电压值,单位是“mV”和“V”,另外在界面上都会有一个触发电平线以指示其相对于信号波形的位置,平板示波器的触发电平调节非常简单,通过手指触摸“Level”上线移动即可。

    触发电平调节又叫同步调节,它使得扫描与被测信号同步。只有触发电平在信号幅度的范围之内时,信号才可能被触发。

    3267201cb6ffcebbfcb98916a5de1d77.png

    触发极性的开关用来选择触发信号的极性。选择正的时候,在信号增加的方向上,当触发信号超过触发电平时就产生触发。选择负的时候,在信号减少的方向上,当触发信号超过触发电平时就产生触发。

    触发极性和触发电平共同决定触发信号的触发点,所用的触发方式在此点上被关注。

    六、触发类型

    用作触发条件的形式有很多,常见的触发类型有:边沿触发、脉宽触发、逻辑触发、N边沿触发、欠幅触发、斜率触发、超时触发、视频触发、串行总线触发等等。

    我们将以边沿触发、脉宽触发和逻辑触发为典型,逐一进行介绍:

    边沿触发:

    边沿触发是最常用最简单也是最有效的触发方式,90%以上的应用都可以只用边沿触发来进行,它是通过查找波形上特定的沿(上升沿或下降沿)来触发信号。

    下图是边沿触发的原理示意:

    以触发电平作为参考,当信号从低于触发电平变化到高于触发电平时产生的触发,就是上升沿触发,反之就是下降沿触发。

    bbc1abd7aaf1823a92ee17f25dfc4c75.png

    现在给示波器端口输入一个简单的正弦波信号,分别设置为上升沿触发和下降沿触发,我们来观察触发位置的变化(顶部中心位置字母“T”表示触发位置)

    83cfccdd0279d4c879bbc9cb180e2666.gif

    脉宽触发:

    根据信号的脉冲宽度产生的触发简称脉宽触发,脉宽的范围定义可以是小于、大于、等于和不等于,根据极性可分为正脉宽和负脉宽。

    f107ebcf7bfa493ed04fbc23b6a565cf.png

    正脉宽:从上升沿与触发电平相交点到相邻的下降沿与触发电平的相交点,两点之间的时间差;

    负脉宽:从下降沿与触发电平相交点到相邻的上升沿与触发电平的相交点,两点之间的时间差。

    efc6358b3f29cc92f25db4991cbe1e5b.png

    现在输入频率为1KHz,即周期为1ms的一个方波信号,使用脉宽触发进行的设置方法如下:

    05dae29df7cecb9289ebdcabf733fc79.gif

    逻辑触发:

    逻辑触发需要设定每个通道的逻辑值,并设置通道之间的逻辑关系(与、或、非等等),当满足该逻辑关系,并达到设定的时间条件之后,任一通道的边沿变化时,就产生触发。

    每个通道的逻辑值可以设置为:高(大于触发电平时为高)、低(于触发电平时为低)、无(无关)。

    下图中,我们设定CH1为高时触发,CH2为低时触发,当同时满足这两个条件时,就能获取稳定的波形。

    bad45943021efd08680678abbcab2a2a.gif

    欠幅触发:

    同过设置高低电平门限,触发那些跨过了一个电平门限但没有跨过另一个电平门限的脉冲。有两种类型可选:正矮脉冲,负矮脉冲。

    bd1e352b88b9244e03671ae958d013f3.png

    672177c61df21fc73dcb7432a087f5a2.png

    斜率触发:

    斜率触发是指当波形从一个电平到达另一个电平的时间符合设定的时间条件时,产生触发。

    正斜率时间:波形从低电平达到高电平所用的时间。

    负斜率时间:波形从高电平达到低电平所用的时间。

    6605ad8f8215ef06bad3d1d63fcc1807.png

    07b01b279a340fb56c9ffd38b3ef82fd.png

    超时触发:

    超时触发是指从信号与触发电平交汇处开始,触发电平之上(或之下)持续的时间超过设定的时间时,产生触发。

    cb2ba4961ab740ec3954887769ed7454.png

    视频触发:

    专门针对视频信号的触发方式,根据视频的制式不同而有所不同,一般有PAL/625、SECAM、NTSC/525、720P、1080I和1080P等制式。视频触发在不同的电压档位都可以触发,可以根据需要调整合适的电压档位观察波形。

    ba4e9013c4620acf02daf87a6cbce0aa.png

    串行总线触发

    常见的有I2C、SPI、CAN、LIN、UART等,需要的朋友可行了解或阅读TO1000系列示波器用户手册。

    c2b54204f984c43e5fb28b65561566e8.png

    七、触发耦合+触发抑制

    如何在触发设置中让波形完美呈现?有一些小细节的作用不可忽视,灵活掌握后,对示波器的使用大有裨益。

    触发耦合

    在常用的设置中,一般设定了触发类型、触发电平,波形就能稳定显示了。但对于噪声比较大的信号,噪声的的存在干扰了信号的准确触发,触发耦合的作用就是用来抑制触发电路中的干扰和噪声。

    6ba192f98553aad87416eb2f225923d9.png

    下面介绍一下常见的耦合方式:

    直流(DC)耦合:触发源信号交流和直流成分都被送入触发电路。

    交流(AC)耦合:触发源信号直流成分被滤去。适用于观察从低频到较高频率的信号。

    高频(HF)抑制:触发源信号中特定频率以上的信号都被滤去。适用于观察含有高频干扰的信号。

    低频(LF)抑制:触发源信号中特定频率以下的信号都被滤去。适用于观察含有低频干扰的信号。

    噪声(Noise)抑制:用低灵敏度的直流耦合来抑制触发源信号中的噪声成分。适用于观察含有高频噪声干扰的信号。

    触发耦合其实就是一种对触发信号的低通或高通滤波。因此可对噪声大的信号加入“高频抑制”耦合,过滤掉其中高频部分,

    触发抑制

    在触发设置中,触发抑制的功能一般会被人忽略。按照定义,抑制是定义两次触发之间的最少时间间隔。当示波器触发一次后,会进入触发释抑时间计数,在此时间内触发功能会被抑制,即使信号满足触发条件,系统也不会标记为触发点。

    c4ea75ab6a114a01781a0eadb5aa7d8b.png

    触发抑制时间的设置对偶发性多边沿的信号捕获极为好用,使得原来图像不稳定的波形马上清晰。若触发释抑时间没有设置好,示波器将会把不同边沿的信号作为触发点,导致不一致的波形重叠在一起,造成波形显示不稳定。


    触发是目的性很强的操作,也就是说需知道信号异常,才会知道要设定怎样的触发条件。那如何快速发现异常,这应该是设置合理触发的前提,TO1000系列平板示波器拥有最高13万次每秒的波形捕获率,长达28Mpts的存储深度和丰富的触发类型,可以帮助我们在复杂多变的信号中快速定位异常部分。

    捕捉异常信号实例:

    第一步:通过电路故障怀疑信号中可能存在小概率的异常事件;

    第二步:打开示波器高刷新模式,观察到一个高电平的偶发信号;

    32566712f3ee41321b79289d62323b41.gif

    第三步:根据异常信号的特性,选择最为合适的边沿触发,调整触发电平直至稳定异常信号。

    b089c428676a292e01c2d36fdf609686.gif
    展开全文
  • 回答上面的问题,就需要引入epoll的触发方式了,分别水平触发和边沿触发。 二 what epoll水平触发: 只要监听的文件描述符中有数据,就会触发epoll_wait有返回值,这默认的epoll_wait的方式; epoll边沿触发 : ...
  • 于是具有多通道输入的逻辑分析仪就应运而生,逻辑分析仪不但解决了示波器输入通道不足的问题,还提供了更加强大的触发功能和分析功能,对于数字电路开发系统来说,逻辑分析仪无疑一个很好的测试分析工具。...
  • 我们先简单回顾下什么是示波器的触发。由于信号无时无刻都在变化,如果一股脑的都把他们显示在示波器上,就会很乱,根本无法让我们看清楚,从而也就无法观察信号来解决问题。考虑到信号大多数时候都以某种规律周期...
  • 触发器的基本特点触发器组成时序逻辑电路的基本单元电路,它一种有记忆功能的逻辑部件。触发器的基本特点:(1)具有两个互补输出端Q和/Q;(2)具有“0”态和“1”态两个稳定状态;(3)在外部信号作用下可实现状态...
  • 无论模拟还是数字示波器触发,都有各种自动触发机制来增强。本文对示波器触发电路及其设计方案的概述,介绍了触发发生器的基础知识以及一些增强功能。示波器触发系统在前面板上对应两个基本控制装置:触发电平...
  • 无论模拟还是数字示波器触发,都有各种自动触发机制来增强。本文对示波器触发电路及其设计方案的概述,介绍了触发发生器的基础知识以及一些增强功能。示波器触发系统在前面板上对应两个基本控制装置:触发电平...
  • 前言PWM触发ADC进行采样,对于电机控制来说非常重要的一环,做矢量控制,能否运行,电流采样重中之重,因此电流采样的时刻控制非常重要,本节就接着上篇文章的中心对齐模式,讲解,中心对齐模式下的PWM触发ADC...
  • 最近在研究计算机里的基本逻辑电路,想到一个问题:为什么CPU需要时钟这样的概念?首先考虑如下逻辑电路:当A=B=1时,Q=0。当输入信号发生变化时,逻辑元件不会立即对输入变化做出反应,会有一个传播时延...
  • 时间的重要性不言而喻,加上时间这个维度就如同X-Y的平面加上了一个Z轴,如同打开了一个新的世界。所以今天我们就要来聊聊时序电路。在时序电路中,电路任何时刻的稳定状态输出不仅取决于...总之……时序电路有记...
  • 有些事情并不能持续的深入研究,唯有市场的持续需求不断刺激技术进步,就像战争那样,技术才可能有巨大的飞跃。另外,一些其他技术的进步,比如电子计算机,也与仪器的发展相辅而成,这也带来了...为什么苏联没有做...
  • 之前有朋友讲,有“十级汉服...可是后来,看到一些商家产品的图片,才发现,这是边沿装饰啊!那边沿装饰确实不是特别合适,因为目前而言边沿装饰确实不见于清中叶以前的汉服。首先,我们需得首先回顾一下汉服的定义...
  • 电路板中高频信号为什么会干扰通讯数据,干扰路径在哪里?...在工作中,经常遇到数字电路之间的干扰问题,尤其数字信号的波形边沿处会产生尖峰震荡,这个尖峰如何产生的?在说明这些问题之前,先来学...
  • 它也整形电路的一种。例如电视信号在传输过程中会造成失真,为了使脉冲波形恢复原样,接收机里就要用箝位电路把波形顶部箝制在某个固定电平上。下图中反相器输出端上就有一个箝位二极管 VD 。如果没有这个二极管,...
  • 1.中断有电平和边沿两种,电平就是为某种电平(高或者低电平)时触发中断,边沿触发市指从高电平向低电平,或者低电平到高电平跳变时触发 2.如果串口先后接收到4个char型数据,分别设为a,b,c,d,则转换为int型...
  • 119-epoll(触发模式)

    千次阅读 热门讨论 2017-03-24 20:06:19
    1. 触发方式我知道,作为初始者的你已经懵圈了,触发是什么意思?在英文原文,水平触发为 level-triggered 而边沿触发为 edge-triggered. 关键在于 triggered 这个单词。来看看 Collins 词典对 trig
  • 4.1.5 用过哪些Map类,都有什么区别,HashMap是线程安全的吗,并发下使用的Map是什么,他们内部原理分别是什么,比如存储方式,hashcode,扩容,默认容量等。 4.1.6 JAVA8的ConcurrentHashMap为什么放弃了分段锁,有...

空空如也

空空如也

1 2
收藏数 22
精华内容 8
关键字:

边沿触发是什么意思