分享
  1. 首页
  2. 文章

Golang中重新open 已经被close的chan管道

GoWKH · · 2824 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

最近忽发奇想,在Golang中怎么把,已经关闭的管道再次打开。这样就避免了,每次都要make一个新的chan,节省内存申请和GC的时间,查看go的源代码,经过简单地摸索后,实现了,示例代码如下。
func TestUnsafe(t *testing.T) {
	c1 = make(chan struct{}, 10)
	c1 <- struct{}{}
	<-c1
	close(c1)
	p := (*unsafe.Pointer)(unsafe.Pointer(&c1))
	c := (*hchan)(*p)
	c.closed = 0//打开被关闭的chan
	c1 <- struct{}{}
	<-c1
}
func TestSafe(t *testing.T) {
	c1 = make(chan struct{}, 10)
	c1 <- struct{}{}
	<-c1
	close(c1)
	p := (*unsafe.Pointer)(unsafe.Pointer(&c1))
	c := (*hchan)(*p)
	atomic.CompareAndSwapUint32(&c.closed, 1, 0) //打开被关闭的chan
	c1 <- struct{}{}
	<-c1
} 

最终代码 发布到 github.com/yireyun/go-openc,有兴趣的朋友可以看看。

这种做法最大的缺点是如果go的runtime的数据结构发生变化,将不再可行。因此增加了在init方法中检测的go内核数据结构是否发生变化的代码,性能测试结果如下。

BenchmarkMakeCloseChan-4 	20000000	 90.9 ns/op
--- BENCH: BenchmarkMakeCloseChan-4(每次新建在关闭的性能)
go1.7.4, Times: 1, use: 0s 0s/op
go1.7.4, Times: 100, use: 0s 0s/op
go1.7.4, Times: 10000, use: 998.3μs 99ns/op
go1.7.4, Times: 1000000, use: 91.0664ms 91ns/op
go1.7.4, Times: 20000000, use: 1.8185449s 90ns/op
BenchmarkCloseOpenChan-4 	50000000	 29.5 ns/op
--- BENCH: BenchmarkCloseOpenChan-4(非安全打开的性能)
go1.7.4, Times: 1, use: 0s 0s/op
go1.7.4, Times: 100, use: 0s 0s/op
go1.7.4, Times: 10000, use: 0s 0s/op
go1.7.4, Times: 1000000, use: 28.5199ms 28ns/op
go1.7.4, Times: 50000000, use: 1.473497s 29ns/op
BenchmarkCloseOpenChanSync-4 	30000000	 44.9 ns/op
--- BENCH: BenchmarkCloseOpenChanSync-4(安全打开的性能)
go1.7.4, Times: 1, use: 0s 0s/op
go1.7.4, Times: 100, use: 0s 0s/op
go1.7.4, Times: 10000, use: 498.2μs 49ns/op
go1.7.4, Times: 1000000, use: 47.5278ms 47ns/op
go1.7.4, Times: 30000000, use: 1.3479236s 44ns/op
PASS
ok 	github.com/yireyun/go-openc	8.235s

有疑问加站长微信联系(非本文作者)

本文来自:知乎专栏

感谢作者:GoWKH

查看原文:Golang中重新open 已经被close的chan管道

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
2824 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏