首页 > 其他分享 >golang channel 封装

golang channel 封装

时间:2024-05-11 23:30:45浏览次数:27  
标签:封装 closed nil golang func close channel 通道

对于closed或nil通道,规则如下:

  • 无论收发,nil通道都会阻塞。
  • 不能关闭nil通道。
  • 重复关闭通道,引发panic !
  • 向已关闭通道发送数据,引发 panic!
  • 从已关闭通道接收数据,返回缓冲数据或零值。

nil通道是指没有make的变量。鉴于通道关闭后,所有基于此的阻塞都被解除,可用作通知。

没有判断通道是否已被关闭的直接方法,只能透过收发模式获知,

操作 已关闭的channel nil channel
如果channel中还有数据,可以继续读取;如果channel中没有数据了, 可以读到零值 永久阻塞(deadlock)
panic: send on closed channel 永久阻塞(deadlock)
close panic: close of closed channel panic: close of nil channel

为避免重复关闭,可包装close函数。也可以类似方式封装send recv 操作。

func closechan[T any](c chan T) {
	defer func(){
		recover()
	}()

	close(c)
}

func main() {
	c := make(chan int, 2)

	closechan(c)
	closechan(c)
}

可使用 sync.RWMutex、sync.Once 优化设计。

type Queue[T any] struct {
	sync.Mutex	

	ch     chan T
	cap    int
	closed bool
}

func NewQueue[T any](cap int) *Queue[T] {
	return &Queue[T]{
		ch: make(chan T, cap),
	}
}

func (q *Queue[T]) Close() {
	q.Lock()
	defer q.Unlock()

	if !q.closed {
		close(q.ch)
		q.closed = true
	}
}

func (q *Queue[T]) IsClosed() bool {
	q.Lock()
	defer q.Unlock()

	return q.closed
}

// ---------------------------------

func main() {
	var wg sync.WaitGroup
	q := NewQueue[int](3)

	for i := 0; i < 10; i++ {
		wg.Add(1)

		go func() {
			defer wg.Done()
			defer q.Close()
			println(q.IsClosed())
		}()
	}

	wg.Wait()
}

利用 nil 通道阻止退出。

func main() {
    <-(chan struct{})(nil)    // select{}
}

 

 

标签:封装,closed,nil,golang,func,close,channel,通道
From: https://www.cnblogs.com/codestack/p/18187366

相关文章

  • Vue项目中有封装过axios吗?主要是封装哪方面的?
    一、axios是什么axios 是一个轻量的 HTTP客户端基于 XMLHttpRequest 服务来执行 HTTP 请求,支持丰富的配置,支持 Promise,支持浏览器端和 Node.js 端。自Vue2.0起,尤大宣布取消对 vue-resource 的官方推荐,转而推荐 axios。现在 axios 已经成为大部分 Vue 开发者的......
  • ELL-8051-LIB - 面向8051的高效低封装函数库+KLite - 简洁易用的嵌入式操作系统内核
    1、Arm-2D-基于Cortex-M的2D图形加速库ARM官方出品的2D图形加速库,在Cortex-M55系统频率8MHz下就可以实现30fps的渲染(6图层。320x240,rgb565)。项目主页: https://github.com/ARM-software/EndpointAI/tree/master/Kernels/Research/Arm-2DArm-2D库特性包括但不限于:*......
  • 使用js有效括号匹配封装函数
    点击查看代码functionisValidParentheses(str){//定义一个栈,用于存储待匹配的左括号letstack=[];//定义一个对象,用于快速判断括号是否成对constpairs={')':'(','}':'{',']':'['};//遍历输入字符串for(let......
  • 【golang】go语言学习需要注意的点
     (学习可参考菜鸟教程:https://www.runoob.com/go/go-basic-syntax.html) 1.Go编译生成的exe程序在后台运行(不闪过console窗口)gobuild-ldflags"-s-w-H=windowsgui"-s省略符号表和调试信息-wOmittheDWARFsymboltable省略DWARF符号表-Hwindowsgui不打印信......
  • Python进阶之封装
    【一】面向对象的三大特性面向对象的三大特性:封装、继承、多态其中最重要的就是封装,封装就是将数据和功能整合到一起我们可以对封装在类和对象中的属性进行访问的控制,有隐藏的和开发的接口【1】什么是封装封装是对具体对象的一种抽象封装就是将某些数据和功能隐藏起来,只......
  • node.js 封装操作文件类
    constfs=require('fs');constpath=require('path');classFile{constructor(fileName,name,ext,isFile,size,createTime,updateTime){this.fileName=fileName;this.name=name;this.ext=ext;......
  • 继承介绍、经典类和新式类、继承和抽象、封装和派生、组合
    【一】继承介绍继承是一种创建新类的方式,新建的类可以继承一个或多个父类(python支持多继承),父类又可称为基类或超类,新建的类称为派生类或子类。子类会“遗传”父类的属性,从而解决代码重用问题(去掉冗余的代码)继承:单继承:继承一个父类的子类多继承:继承多个父类的子类c......
  • React文本溢出组件封装以及高亮提示
    React文本溢出组件封装以及高亮提示Abbr组件:使用场景:当我们需要设置支持最大行数时进行省略展示当我们需要设置支持设置超过多少字符进行省略展示当我们需要设置支持关键字高亮展示(有点问题,当关键字被裁剪成...之后,就无法高亮)当我们需要支持忽略大小写高亮当我们需要支持......
  • 面向对象的三大特性、封装的介绍及属性、装饰器property、员工管理系统
    【一】面向对象的三大特性封装:封装指的就是把数据与功能都整合到一起继承多态【二】什么是封装封装是对具体对象的一种抽象意思就是将某部分功能和代码隐藏起来,在程序外边看不到,只能在程序内部使用【三】为什么要封装?封装数据的主要原因是:保护隐私(把不想别人......
  • golang项目包管理(go module模式)
     修改GO111MODULE和GOPROXYexportGO111MODULE=onexportGOPROXY=https://goproxy.io#GO111MODULE默认为auto,当项目存在go.mod,会自动启用gomodule模式。这里还是直接开启比较好。初始化go.modgomodinit安装依赖goget依赖包#下载的依赖包放在GOPATH下pkg下的m......