本篇文章我们用Go实现一个自定义事件注册并等待唤醒的机制,其中涉及到的链表操作可以参考上一篇文章。文章参考自:https://github.com/brewlin/net-protocol

1.自定义唤醒事件

type EventMask uint16

const (
EventIn EventMask = 0x01
EventPri EventMask = 0x02
EventOut EventMask = 0x04
EventErr EventMask = 0x08
EventHUp EventMask = 0x10
EventNVal EventMask = 0x20
)

2.等待对象

type Entry struct {
Context interface{}
Callback EntryCallback
mask EventMask
ilist.Entry
}

3.等待对象被唤醒后的回调

type EntryCallback interface {
Callback(e *Entry)
}

4.EntryCallback接口的实现

Callback向等待对象的channel发送值以唤醒channel上的等待协程。

type channelCallback struct{}

func (*channelCallback) Callback(e *Entry) {
ch := e.Context.(chan struct{})
select {
case ch <- struct{}{}:
default:
}
}

5.初始化等待对象

这里的channel将会用于阻塞未被唤醒时的协程。

func NewChannelEntry(c chan struct{}) (Entry, chan struct{}) {
if c == nil {
c = make(chan struct{}, 1)
} return Entry{Context: c, Callback: &channelCallback{}}, c
}

6.等待队列

type Queue struct {
list ilist.List
mu sync.RWMutex
}

7.事件注册和事件注销

// EventRegister 注册等待对象
func (q *Queue) EventRegister(e *Entry, mask EventMask) {
q.mu.Lock()
e.mask = mask
q.list.PushBack(e)
q.mu.Unlock()
} // EventUnregister 注销等待对象
func (q *Queue) EventUnregister(e *Entry) {
q.mu.Lock()
q.list.Remove(e)
q.mu.Unlock()
}

8.事件唤醒

根据事件类型,通过回调函数向channel发送值以唤醒等待队列中的所有相关等待对象。

func (q *Queue) Notify(mask EventMask) {
q.mu.RLock()
for it := q.list.Front(); it != nil; it = it.Next() {
e := it.(*Entry)
if mask&e.mask != 0 {
e.Callback.Callback(e)
}
}
q.mu.RUnlock()
}

9.其他方法

// Events 返回已注册的事件类型
func (q *Queue) Events() EventMask {
ret := EventMask(0) q.mu.RLock()
for it := q.list.Front(); it != nil; it = it.Next() {
e := it.(*Entry)
ret |= e.mask
}
q.mu.RUnlock() return ret
} // IsEmpty 等待队列是否为空
func (q *Queue) IsEmpty() bool {
q.mu.Lock()
defer q.mu.Unlock() return q.list.Front() == nil
}

10.使用示例

func main() {
var wq waiter.Queue waitEntry, notifyCh := waiter.NewChannelEntry(nil)
wq.EventRegister(&waitEntry, waiter.EventIn)
defer wq.EventUnregister(&waitEntry) go func() {
for {
time.Sleep(time.Second)
wq.Notify(waiter.EventIn)
}
}() for {
<-notifyCh
fmt.Println("waked")
}
}

Go组件库总结之事件注册唤醒的更多相关文章

  1. 属性.native用于解决第三方el组件库@click事件无效

    描述 有时发现用一些第三方的组件库时,例如一个封装好的button按钮<el-butten>,绑定点击事件却没有任何作用,这时便需要加 .native 原因: v-on 是对 Vue 的事 ...

  2. vue 复习篇. 注册全局组件,和 组件库

    初篇 ============================================================== 1. 编写loading组件(components/Loading/ ...

  3. 前端笔记之Vue(四)UI组件库&Vuex&虚拟服务器初识

    一.日历组件 new Date()的月份是从0开始的. 下面表达式是:2018年6月1日 new Date(2018, 5, 1); 下面表达式是:2018年5月1日 new Date(2018, 4 ...

  4. 如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源

    1.前言 关于微信内部正在使用的网络层封装库Mars开源的消息,1个多月前就已满天飞(参见<微信Mars:微信内部正在使用的网络层封装库,即将开源>),不过微信团队没有失约,微信Mars ...

  5. 【转】如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源

    网上看到关于微信官方的跨平台跨业务的终端基础组件Mars的介绍文章,转载这这里.源代码: https://github.com/Tencent/mars作者:男人链接:https://zhuanlan ...

  6. vue统计组件库和ui框架

    UI组件 element ★13489 - 饿了么出品的Vue2的web UI工具套件 Vux ★8133 - 基于Vue和WeUI的组件库 iview ★6634 - 基于 Vuejs 的开源 UI ...

  7. Blazor组件提交全记录: FullScreen 全屏按钮/全屏服务 (BootstrapBlazor - Bootstrap 风格的 Blazor UI 组件库)

    Blazor 简介 Blazor 是一个使用 .NET 生成的交互式客户端 Web UI 的框架.和前端同学所熟知的 Vue.React.Angular 有巨大差异. 其最大的特色是使用 C# 代码( ...

  8. Vue3 企业级优雅实战 - 组件库框架 - 1 搭建 pnpm monorepo

    前两篇文章分享了基于 vite3 vue3 的组件库基础工程 vue3-component-library-archetype 和用于快速创建该工程的工具 yyg-cli,但在中大型的企业级项目中,通 ...

  9. Vue3 企业级优雅实战 - 组件库框架 - 10 实现组件库 cli - 下

    上文创建了一堆 utils.component-info,并实现了新组件模块相关目录和文件的创建.本文继续实现后面的内容. 1 组件样式文件并导入 在 src/service 目录中创建 init-s ...

  10. 2015.5.2-2015.5.8 Tip jQuery ,前端组件库,inline-block元素间距等

    有忙于它事,故延迟了,但在坚持! 1.Tip jQuery   2.给span加display: inline-block; 怎样能对齐? 解决方法:vertical-align: bottom:   ...

随机推荐

  1. elasticsearch之日期类型有点怪

    一.Date类型简介 elasticsearch通过JSON格式来承载数据的,而JSON中是没有Date对应的数据类型的,但是elasticsearch可以通过以下三种方式处理JSON承载的Date数 ...

  2. java数据库连接池笔记

    (课程笔记来源于跟着老师敲,老师是黑马程序b站白嫖课程~) #数据库连接池: 1.概念:就是一个容器(集合),存放数据连接的容器   当容器初始化好后,容器会被创建,容器中会申请一些连接对象,当用户来 ...

  3. 2.17 win32 按钮事件的处理

    按钮的本质就是窗口 点击查看代码 void CreateButton(HWND hwnd) { HWND hwndPushButton; HWND hwndCheckBox; HWND hwndRad ...

  4. 安卓逆向 创建自己一个SO库

    要求 1.能调用java中的方法 2.有返回值 如何完成一个SO ? public native String getText(); //第一肯定是得创建一个方法 cmd指令自动生成对应接口 生成完后 ...

  5. python爬取网页的多种方式以及保存方法

    爬取网页信息并保存 bs4和lxml都是用来将接收的数据解析html 1.bs4+excel(openpyxl): import requests from bs4 import BeautifulS ...

  6. Yapi安装配置(CentOs)

    环境要求 nodejs(7.6+) mongodb(2.6+) git 准备工作 清除yum命令缓存 sudo yum clean all 卸载低版本nodejs yum remove nodejs ...

  7. java学习日记20230301-API文档

    JAVA API java application programming interinterface  应用程序编程接口,是java提供的基本编程接口 在线文档:https://www.matoo ...

  8. Django views.py 增,删,改

    from django import forms from django.shortcuts import render, redirect from app01 import models # Cr ...

  9. VMwareSDN环境配置之git安装

    ------------恢复内容开始------------ null ------------恢复内容结束------------

  10. tasklist

    tasklist是windows下列出进程信息的指令,可配合taskKill来关毕进程 https://learn.microsoft.com/zh-cn/windows-server/adminis ...