(七)注册/注销event事件

Unity插件EasyButton中委托事件的注册和调用 //消息传递Message //时间委托delegate&&event Easy Button事件监听的两种方式 (1).Message ①SeedMessage 向游戏物体发消息,遍历所有脚本中查找符合的定义的方法 然后调用 ②SeedMessageUpwards 向上父类遍历 ③BroadcastMessage 向下子类遍历 (2).Event 调用注册上的方法,是固定 阅读详情

前言

在本小节中,我们将看到event是如何注册到event_base上的,以及如何注销,如何激活等操作,最后还会梳理一下事件的状态是如何变化的。

event_add

int
event_add(struct event *ev, const struct timeval *tv)
{
    struct event_base *base = ev->ev_base;
    const struct eventop *evsel = base->evsel;
    void *evbase = base->evbase;
    int res = 0;

    event_debug((
         "event_add: event: %p, %s%s%scall %p",
         ev,
         ev->ev_events & EV_READ ? "EV_READ " : " ",
         ev->ev_events & EV_WRITE ? "EV_WRITE " : " ",
         tv ? "EV_TIMEOUT " : " ",
         ev->ev_callback));

    assert(!(ev->ev_flags & ~EVLIST_ALL));

    /*
     * prepare for timeout insertion further below, if we get a
     * failure on any step, we should not change any state.
     */
    //如果是个定时事件,在管理定时事件的小根堆上预留一个位置。因为如果有位置,定时事件就不会注册失败。如果没有位置了,那么在这里就先退出了,不会影响到其他地方。原子操作。
    if (tv != NULL && !(ev->ev_flags & EVLIST_TIMEOUT)) {
        if (min_heap_reserve(&base->timeheap,
            1 + min_heap_size(&base->timeheap)) == -1)
            return (-1);  /* ENOMEM == errno */
    }
    //如果事件未注册或激活并且是读/写/信号事件则注册事件(实质上就是调用相关多路I/O复用机制的add函数,比如epoll,则是epoll_ctl)
    if ((ev->ev_events & (EV_READ|EV_WRITE|EV_SIGNAL)) &&
        !(ev->ev_flags & (EVLIST_INSERTED|EVLIST_ACTIVE))) {
        res = evsel->add(evbase, ev);
        //注册成功后,将event插入到注册链表中
        if (res != -1)
            event_queue_insert(base, ev, EVLIST_INSERTED);
    }

    /*
     * we should change the timout state only if the previous event
     * addition succeeded.
     */
    //添加定时事件(所以之前才说事件之间可以进行或操作,这是因为一个I/O事件或信号事件也可能是定时事件)
    if (res != -1 && tv != NULL) {
        struct timeval now;

        /*
         * we already reserved memory above for the case where we
         * are not replacing an exisiting timeout.
         */
        //如果已经在定时事件中,那么移除,添加新的
        if (ev->ev_flags & EVLIST_TIMEOUT)
            event_queue_remove(base, ev, EVLIST_TIMEOUT);

        /* Check if it is active due to a timeout.  Rescheduling
         * this timeout before the callback can be executed
         * removes it from the active list. */
        //检测当前事件的状态是激活态并且激活的事件类型是定时事件(意思就是是因为超时了,然后该事件被激活的)
        //如果是,先从激活事件链表中移出再重新设置定时事件;如果不是,则在其还未超时之前将其插入到管理定时事件的小根堆中
        if ((ev->ev_flags & EVLIST_ACTIVE) &&
            (ev->ev_res & EV_TIMEOUT)) {
            /* See if we are just active executing this
             * event in a loop
             */
            //将调用的次数设置为0
            if (ev->ev_ncalls && ev->ev_pncalls) {
                /* Abort loop */
                *ev->ev_pncalls = 0;
            }
            //执行到此处证明该事件已经是因为超时而被激活过的了,将其移出
            event_queue_remove(base, ev, EVLIST_ACTIVE);
        }
        //计算超时的时间,并插入到小根堆中
        gettime(base, &now);
        evutil_timeradd(&now, tv, &ev->ev_timeout);

        event_debug((
             "event_add: timeout in %ld seconds, call %p",
             tv->tv_sec, ev->ev_callback));

        event_queue_insert(base, ev, EVLIST_TIMEOUT);
    }

    return (res);
}

这个注册event的函数大体上的逻辑还是比较清晰。需要关注的是:

  1. 定时事件比较特殊,需要先在小根堆上预留一个位置,如果失败了,接下来也不用继续了
  2. 当定时事件已经在小根堆是直接移除后再添加,这是因为定时的时间可能不同,那么处于小根堆的位置也不同
  3. 当该定时事件已经因为超时而被激活了,则从管理激活事件的链表中移出再插入到管理超时事件的小根堆中
  4. 注册事件的实质就是让对应的多路I/O机制进行监听,并将其插入到相应的事件链表/小根堆中。

event_del

int
event_del(struct event *ev)
{
    struct event_base *base;
    const struct eventop *evsel;
    void *evbase;

    event_debug(("event_del: %p, callback %p",
         ev, ev->ev_callback));

    /* An event without a base has not been added */
    if (ev->ev_base == NULL)
        return (-1);

    base = ev->ev_base;
    evsel = base->evsel;
    evbase = base->evbase;

    assert(!(ev->ev_flags & ~EVLIST_ALL));

    /* See if we are just active executing this event in a loop */
    if (ev->ev_ncalls && ev->ev_pncalls) {
        /* Abort loop */
        *ev->ev_pncalls = 0;
    }

    if (ev->ev_flags & EVLIST_TIMEOUT)
        event_queue_remove(base, ev, EVLIST_TIMEOUT);

    if (ev->ev_flags & EVLIST_ACTIVE)
        event_queue_remove(base, ev, EVLIST_ACTIVE);

    if (ev->ev_flags & EVLIST_INSERTED) {
        event_queue_remove(base, ev, EVLIST_INSERTED);
        //如果是I/O或signal事件,由于是对应的多路I/O机制在监听,所以注销的时候,也应该取消监听
        return (evsel->del(evbase, ev));
    }

    return (0);
}

这个函数没什么好讲的,无非就是将调用回调函数次数清0并且将该事件从管理各种事件的链表/小根堆上移出,不过如果是已注册的I/O或信号事件,最后一步需要用到对应的多路I/O机制的取消监听的函数。

接下来我们可以来看看event_queue_insert和event_queue_remove这两个函数,因为前面两个函数都有调用。

event_queue_insert

void
event_queue_insert(struct event_base *base, struct event *ev, int queue)
{
    if (ev->ev_flags & queue) {
        /* Double insertion is possible for active events */
        //这是为了避免重复的事件。因为虽然一个事件可以有多种类型,如同时是I/O和定时事件,但是该事件处于激活状态是绝对唯一的。
        if (queue & EVLIST_ACTIVE)
            return;

        event_errx(1, "%s: %p(fd %d) already on queue %x", __func__,
               ev, ev->ev_fd, queue);
    }
    //事件的数量+1
    if (~ev->ev_flags & EVLIST_INTERNAL)
        base->event_count++;
    //接下来就是根据queue设置的事件类型不同而插入到不同的链表/小根堆中了
    ev->ev_flags |= queue;
    switch (queue) {
    //I/O或signal事件,加入到已注册事件链表中
    case EVLIST_INSERTED:
        TAILQ_INSERT_TAIL(&base->eventqueue, ev, ev_next);
        break;
    //已经激活的事件,加入激活事件链表中
    case EVLIST_ACTIVE:
        //已激活事件数+1
        base->event_count_active++;
        TAILQ_INSERT_TAIL(base->activequeues[ev->ev_pri],
            ev,ev_active_next);
        break;
    //定时事件,插入到小根堆中
    case EVLIST_TIMEOUT: {
        min_heap_push(&base->timeheap, ev);
        break;
    }
    default:
        event_errx(1, "%s: unknown queue %x", __func__, queue);
    }
}

event_queue_insert函数的逻辑也很清晰,就是根据事件类型的不同插入到不同的管理事件的数据结构中。里面主要调用了TAILQ_INSERT_TAIL和min_heap_push这两个函数,它们的功能你应该也能猜到,所以我打算后面才来讲它们。

event_queue_remove

void
event_queue_remove(struct event_base *base, struct event *ev, int queue)
{
    if (!(ev->ev_flags & queue))
        event_errx(1, "%s: %p(fd %d) not on queue %x", __func__,
               ev, ev->ev_fd, queue);

    if (~ev->ev_flags & EVLIST_INTERNAL)
        base->event_count--;

    ev->ev_flags &= ~queue;
    switch (queue) {
    case EVLIST_INSERTED:
        TAILQ_REMOVE(&base->eventqueue, ev, ev_next);
        break;
    case EVLIST_ACTIVE:
        base->event_count_active--;
        TAILQ_REMOVE(base->activequeues[ev->ev_pri],
            ev, ev_active_next);
        break;
    case EVLIST_TIMEOUT:
        min_heap_erase(&base->timeheap, ev);
        break;
    default:
        event_errx(1, "%s: unknown queue %x", __func__, queue);
    }
}

这个函数的逻辑和insert大致相同,但是实现的功能相反。

小结

本节我们学到了如何注册/注销一个event,并且看到了事件链表/小根堆的实际应用,我相信此时你对libevent的大致框架已经有一点感觉了。一个事件从初始化,再到被注册到event_base上,根据事件类型的不同存放到不同的管理事件的数据结构上,此时事件处于已经注册但处于未决态,接着等待事件被激活,最后根据优先级被调度。
接下来我们就进入到主循环,看看一个事件到底是如何经过这些过程的。

libevent的event处理框架剖析 前几次剖析了libevent的tail queue和evbuffer,今天来剖析一下它的事件处理框架。这个在剖析evbuffer之前已经大致走过几遍,但思路不是很清晰,是因为我没有用实例去测试event流程。通过这次我学习到了剖析源码不仅要去看源码,而且你要测试它这项接口是怎么用的,不然只会似懂非懂。 首先来看一下event结构体: struct event { TAILQ_ENTR 阅读详情

相关推荐

C# 事件总线 Event Bus

事件总线:是对发布-订阅模式的一种实现,是一种集中式事件处理机制。它允许事件发送者(发布者)与事件接收者(订阅者)之间保持解耦,即它们不需要直接知道对方的存在,只需要通过事件总线进行通信。发布-订阅模式:是一种消息传递模式,消息发送者(称为发布者)不会将消息直接发送给特定的接收者。相反,发布者将发布的消息分类成不同的频道(Channel),不需要知道哪些消息接收者(称为订阅者)会存在或监听这些频道。首先,定义一个事件监听器接口,所有的事件监听器都需要实现这个接口。这个接口包含一个方法,用于处理事件。

学习和分享 2461

event 注册和注销

本节我们依旧来分析event的操作, 接着上节没有讲完的关于event的注册和注销两个功能的实现. event 注册 依旧来看一个event 注册函数的原型 int event_add(struct event *ev, const struct timeval *tv); 相比event_set函数event_add真的很干净. 参数 ev : 将要注册的event事件. 其实实际注册的是e...

啦啦啦 996

C#event EventHandler事件触发

在定义委托时,前面加上event关键字,可以保证该委托不能在外部被随意触发,两者异同: 注册 注销 内部触发 外部触发 delegate += -= Invoke Invoke event delegate += -= Invoke 不允许 所以,event关键字有助于提高类的封装性,物理隔绝代码耦合,...

qq_29136825的博客 3016

QT事件注册(捕获事件)

QObject::event(),    QObject::installEventFilter(),    QWidget::event(),    QCoreApplication::sendEvent(),    QCoreApplication::postEvent(),    QCoreApplication::processEvents().   普通事件:void customEve...

maonianlove的博客 1438

ESP32——事件监听

由于ESP32使用了FreeRTOS实时操作系统,所以避免不了事件,任务的使用。使用事件组件库可以申明其他组件可以向其注册处理程序的事件,代码将在事件发生时执行。这允许松耦合的组件将所需的行为附加到其他组件的状态更改。

chzt的博客 1716

bugku渗透测试4-writeup

三、对这个主机进行全端口的扫描,发现存在22000 ssh端口,那么可以联想到时redis写入公钥来连接主机。又来了一个新的靶场,这个靶场打下来我觉得关键就是信息收集,走了很多的弯路。八、最后一个flag是要去看cms的数据库里面,这个数据库是sqlite。把这个数据库下载下来,登录密码是加密的,就直接用token。一、入口的漏洞是在登录的时候去抓包,修改action的值。六、没想到这个第一台机器的密码,在第二台里面。七、扫描第一台主机、使用之前的密码连接成功。获取最后一台主机的root密码。

vsdfbhsdhsdfh的博客 1295

C++Qt开发——事件处理函数

C++Qt开发——事件处理函数

m0_60259116的博客 3612

手机安装Kali Linux

在数字化时代,信息安全和隐私保护显得尤为重要。,作为一款专业的和工具,因其强大的功能和丰富的资源库而受到广大安全研究者和爱好者的青睐。然而,我们通常只能在传统的电脑设备上安装和使用Kali Linux。那么,有没有可能将也变成一款随身携带的Kali Linux设备呢?答案是肯定的。本文将介绍如何在手机上安装Kali Linux,使你的手机变成一款强大的移动安全工具。,我们需要明确一点,手机安装Kali Linux并非简单的操作,需要对手机进行一定的改造和配置。

2301_80124151的博客 6964

event事件的注册,监听及触发

在JS的业务应用中,现代的js框架基本都提供了自定义事件的封装.. 那么其实现方式是如何的。。本章将一起瞻顾下其原生的event对象,以及最新的DOM3的Event事件支持.. > 1.如何自定义一个事件 var event = document.createEvent(type); * event是通过event创建的实例对...

weixin_30770783的博客 388

Jetbrains IDE 配置上Gemini Code 插件,让你的的编程高效起飞~

Gemini Code Assist是 Google 家产品,基座模型为最新的Gemini 2.5 Pro。本篇实践了在 WebStrom 中Gemini Code Assist插件的高效编程。

2301_76993408的博客 4595

用STC8单片机解码EV1527遥控信号:从波形分析到C代码实现(附完整库)

本文详细介绍了如何使用STC8单片机解码EV1527遥控信号,从波形分析到C代码实现的完整过程。内容包括EV1527协议解析、硬件搭建、信号捕获技巧、解码算法实现及优化策略,并附有完整库代码,帮助开发者快速实现智能家居设备的无线控制。

weixin_34093995的博客 295

Libevent库源码介绍及TCP后端服务器

Libevent 是一个轻量级的开源高性能事件通知库,主要有以下几个亮点:事件驱动,高性能;轻量级,专注于网络,源代码相当精炼、易读;跨平台,支持 Windows、 Linux、 *BSD 和 Mac Os;支持多种 I/O 多路复用技术, epoll、 poll、 dev/poll、 select 和 kqueue 等;支持 I/O,定时器和信号等事件;注册事件优先级.

遛遛马,务务农 755

无人机巡检提速3倍!YOLOv8n+OpenVINO让Jetson Nano跑25FPS,还能多飞25分钟

摘要(149字): 针对无人机巡检中Jetson Nano算力不足导致的帧率低、首次推理延迟高、续航短等问题,提出YOLOv8n+OpenVINO联合优化方案: 模型轻量化:YOLOv8n参数量仅3.2M(较v8s减少71%),Jetson Nano帧率从8FPS提升至15FPS(原生),绝缘子裂纹召回率仅降3%; OpenVINO加速:AUTO模式动态分配CPU/GPU算力,首次推理延迟从500ms降至200ms,帧率再优化至25FPS; 能效提升:功耗降低40%,单次续航延长25分钟。方案已落地电力/林

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1242

Event事件的注册和注销

通过+/-来注册和注销定义的Event。 如下通过匿名Event举例: EventHandler _testHandler = null; //注册 TestClickEvent += _testHandler = { o,e } => { ........ } //注销 TestClickEvent -= _testHandler ;

tianyu0910的专栏 703

智能车八邻域图像算法

智能车八邻域图像算法

技术缝合怪的博客 4万+

在Simulink中进行基于强化学习控制策略的三相逆变器仿真

本文详细介绍了在Simulink中实现基于强化学习控制策略的三相逆变器仿真的完整流程。主要内容包括:1)准备工作,确保MATLAB/Simulink及相关工具箱安装;2)构建三相逆变器基础模型,包含电源、全桥电路、LC滤波器和负载;3)重点阐述强化学习控制器设计,涉及状态空间、动作空间定义,奖励函数设计和算法选择;4)实现控制逻辑,包括环境创建、代理配置和训练过程;5)仿真设置与结果分析。文章强调了模型调试优化的重要性,并建议结合文献研究提升控制效果。该方案为开发自适应电力电子控制系统提供了实用指南。

amy_mhd的博客 271

Unity Event注册与注销

参考https://www.cnblogs.com/horse/archive/2010/02/19/1669333.html 因为程序一直处在运行中,所以主窗体对象一直驻留内存中并保持着自身的状态(它没有的disposed),所以,每次子窗体创建时,主窗体都会注册它的OnRequestUserList事件,同样的,该子窗体在加载时,自身也会把主窗体的OnUserListCreated事件注册...

yaoyutian的博客 1692

LDRA Testbed(TBrun)软件单元测试_实例讲解(对多次调用的函数打桩)

在之前的文章《LDRA Testbed(TBrun)软件单元测试_操作指南》中,已经讲解了如何使用TBrun进行软件单元测试的基本操作步骤。本篇文章将结合实例进一步讲解被测函数中包含多次调用其他函数时,如何对其打桩来实现测试目的(详细的操作流程本文不再重述,若有不清楚的,可以结合之前的操作指南一起来看)。本文以一个被测函数作为示例,讲解了如何使用Testbed(TBrun)对涉及到多次调用其他函数的被测函数进行单元测试。本文的示例可能比较简单,但是思路、方法和流程都是通用的,希望对大家有所帮助。

文章主要涉及嵌入式软件开发、测试、项目管理等,欢迎交流,共同进步。 1462

esp-idf 之事件循环(Event Loop)例程详解

本文是将Default Event Loop:esp-idf/examples/system/esp_event/default_event_loop at release/v3.3 · espressif/esp-idf 例程内的README和代码注释翻译一下,便于各位看官理解并理顺思路。 README 事件循环库Event Loop Library (‘esp_event’) 默认事件循环例程Default Event Loop Example 本例程是事件循环库的一个示例。为了保持简单,示例仅限于使用

SimonLiu的博客 9736

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

【unity实战】事件(Event)的基本实战使用

【unity小技巧】委托(Delegate)的基础使用和介绍这期来讲讲事件,使用你会发现它和委托真的很像,那么他们具体有什么区别呢?委托(Delegate)委托是一种类型,用于引用一个或多个方法。委托可以看作是函数指针或函数的代理。委托用于实现回调函数、事件处理和方法的动态绑定。委托是一种类型安全的方式来封装方法调用。事件(Event)事件是建立在委托之上的高级概念,它提供了一种更加简洁、安全的方式来实现观察者模式。事件使用委托来通知其他对象或类,当特定情况发生时,让它们执行相应的操作。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 1万+

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

C# 事件(event)

事件是一种特殊的多播委托,仅可以从声明事件的类(或派生类)或结构(发布服务器类)中对其进行调用。如果其他类或结构订阅该事件,则在发布服务器类引发该事件时,将调用其事件处理程序方法可以将事件标记为publicprivateprotectedinternal或。这些访问修饰符定义该类的用户访问该事件的方式。事件在我们平时开发中用的还是比较多的,大部分时候用在框架中,比如 Winform 中的 Timer 组件,如下面代码,Timer.Elapsed 就是一个事件//实例化Timer类,

熊思雨的博客 7775

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Linux input子系统分析之三 input device/handler注册与注销分析

上一章我们分析了input子系统主要的数据结构,本章我们主要分析input hander、input device、input handle的注册与注销。本章的主要内容如下: 一、input device的注册与注销说明 二、input handler的注册与注销说明 三、input handle的注册与注销说明 四、input事件分发说明 在分析input device、input handler、input handle的注册与注销时,我们还是看下这些数据结构...

lickylin的专栏 1385

net_device的注册与注销

net_device对象只有通过register_netdev()注册到系统后才能被外部感知到。类似的,在释放之前需要通过unregister_netdev()将net_device对象先从系统中注销。这篇笔记分析了这两个过程的实现。

九天小哥的专栏 5377

委托的注册及注销+观察者模式

所以取消public,封闭它,我们可以自己书写两个方法,供外部注册与注销,委托调用在子方法里调用,这样封装委托变量可以使它更安全,这个就叫做事件。一系列对象来监听另外一个对象的行为,被监听者一旦触发事件/发布消息,则被所有监听者收到,然后执行自己的行为。就是使用委托/事件,让一系列对象把他们的行为来注册到我的委托中去。委托变量如果公开出去,很不安全,外部可以随意调用。小花想在打铃时去打羽毛球。小明想在打铃的时候去买东西吃,2.只能自己去调用自己的委托。小红想在打铃时开始练习,小张想在打铃时去打水,

m0_74236534的博客 593

libevent事件处理框架:event_base

回想Reactor 模式的几个基本组件, 本节讲解的部分对应于Reactor 框架组件。在libevent中,Reactor 框架组件表现为event_base结构体,结构体声明如下,它位于event-internal.h 文件中: struct event_base { const struct eventop * evsel ; void * evbase; int event_count ;...

shayne000的博客 752

libevent学习笔记七:libevent事件处理框架剖析

libevent学习笔记七:libevent事件处理框架剖析 前面几节已经对libevent的事件处理框架和event结构体做了描述和介绍,现在是需要进一步的深入剖析的时候了,更深入的对libevent事件的详细处理流程进行解析和理解,本节具体的将分析libevent的事件处理框架event_base和libevent注册、删除事件的流程,可结合前一节libevent对event的管理的流程进行...

jyl_sh的专栏 1266
上一篇: (六)初始化并设置event
下一篇: (八)事件主循环
UKey_
博客等级 码龄10年 258粉丝 186原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值