Go组件库总结之事件注册唤醒
本篇文章我们用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组件库总结之事件注册唤醒的更多相关文章
- 属性.native用于解决第三方el组件库@click事件无效
描述 有时发现用一些第三方的组件库时,例如一个封装好的button按钮<el-butten>,绑定点击事件却没有任何作用,这时便需要加 .native 原因: v-on 是对 Vue 的事 ...
- vue 复习篇. 注册全局组件,和 组件库
初篇 ============================================================== 1. 编写loading组件(components/Loading/ ...
- 前端笔记之Vue(四)UI组件库&Vuex&虚拟服务器初识
一.日历组件 new Date()的月份是从0开始的. 下面表达式是:2018年6月1日 new Date(2018, 5, 1); 下面表达式是:2018年5月1日 new Date(2018, 4 ...
- 如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源
1.前言 关于微信内部正在使用的网络层封装库Mars开源的消息,1个多月前就已满天飞(参见<微信Mars:微信内部正在使用的网络层封装库,即将开源>),不过微信团队没有失约,微信Mars ...
- 【转】如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源
网上看到关于微信官方的跨平台跨业务的终端基础组件Mars的介绍文章,转载这这里.源代码: https://github.com/Tencent/mars作者:男人链接:https://zhuanlan ...
- vue统计组件库和ui框架
UI组件 element ★13489 - 饿了么出品的Vue2的web UI工具套件 Vux ★8133 - 基于Vue和WeUI的组件库 iview ★6634 - 基于 Vuejs 的开源 UI ...
- Blazor组件提交全记录: FullScreen 全屏按钮/全屏服务 (BootstrapBlazor - Bootstrap 风格的 Blazor UI 组件库)
Blazor 简介 Blazor 是一个使用 .NET 生成的交互式客户端 Web UI 的框架.和前端同学所熟知的 Vue.React.Angular 有巨大差异. 其最大的特色是使用 C# 代码( ...
- Vue3 企业级优雅实战 - 组件库框架 - 1 搭建 pnpm monorepo
前两篇文章分享了基于 vite3 vue3 的组件库基础工程 vue3-component-library-archetype 和用于快速创建该工程的工具 yyg-cli,但在中大型的企业级项目中,通 ...
- Vue3 企业级优雅实战 - 组件库框架 - 10 实现组件库 cli - 下
上文创建了一堆 utils.component-info,并实现了新组件模块相关目录和文件的创建.本文继续实现后面的内容. 1 组件样式文件并导入 在 src/service 目录中创建 init-s ...
- 2015.5.2-2015.5.8 Tip jQuery ,前端组件库,inline-block元素间距等
有忙于它事,故延迟了,但在坚持! 1.Tip jQuery 2.给span加display: inline-block; 怎样能对齐? 解决方法:vertical-align: bottom: ...
随机推荐
- Cpp 友元简述
友元函数,友元类 使用友元,主要是易于直接访问数据,但友元本质是以破坏封装性为代价. 下例引用于: <C++程序设计(第2版)> 友元声明位置由程序设计者决定,且不受类中public.pr ...
- Listen 1音乐播放器
Listen 1 Listen 1可以搜索和播放来自网易云音乐,QQ音乐,酷狗音乐,酷我音乐,Bilibili,咪咕音乐网站的歌曲,让你的曲库更全面.还支持歌单功能,你可以方便的播放,收藏和创建自己的 ...
- .NET周报 【2月第2期 2023-02-11】
国内文章 SQLSERVER的truncate和delete有区别吗? https://mp.weixin.qq.com/s/wTIeW8rjj3cRzoaQcg2sOw 在面试中我相信有很多朋友会被 ...
- OpenMP Sections Construct 实现原理以及源码分析
OpenMP Sections Construct 实现原理以及源码分析 前言 在本篇文章当中主要给大家介绍 OpenMP 当中主要给大家介绍 OpenMP 当中 sections construct ...
- vue3 vite 使用NProgress.js纳米级进度条
NProgress.js 官网:https://ricostacruz.com/nprogress/ 安装方式: npm install nprogress 使用方法 在router 的index.j ...
- 跳板攻击之:lcx 端口转发
跳板攻击之:lcx 端口转发 郑重声明: 本笔记编写目的只用于安全知识提升,并与更多人共享安全知识,切勿使用笔记中的技术进行违法活动,利用笔记中的技术造成的后果与作者本人无关.倡导维护网络安全人人有责 ...
- Android:Banner 和 Glide 在 Fragment 中实现轮播图
添加依赖信息 引入 Banner 和 Glide 依赖信息: dependencies { implementation 'io.github.youth5201314:banner:2.2.2' i ...
- react-native-sortable-list没有渲染数据
问题如题. 原因是我的order数组为空数组,应该将数组元素补充上.
- vue中引入字体
前言: 做大屏 项目需要引入字体做个记录一.先看看效果 二.实现1.下载字体文件 分享一个下载开源字体网站: https://www.dafont.com/theme.php2.文件放到项目中 可以 ...
- yile接口
后台接口: ---------------------------更改订单状态接口(需要主站长账号权限,主站要有接口权限)更改订单状态(可批量更新),如需退款/退单请用订单退款退单接口,如需更新订单数 ...