关于godailylib:为-tunny-提交的一次-PR

24次阅读

共计 1464 个字符,预计需要花费 4 分钟才能阅读完成。

背景

上周我写了一篇文章 Go 每日一库之 ants,深刻分析了 ants 这个 goroutine 池的实现。在重复浏览了多遍 panjf2000 对于 ants 的起源的文章——GMP 并发调度器深度解析之手撸一个高性能 goroutine pool,我感觉播种满满。这篇文章对于了解 Go 的 goroutine 并发机制有很大的参考价值,强烈建议一读。而后我花了几个小时工夫具体浏览了 ants 的源码,代码写的很棒,十分柔美。而后我写了一遍文章剖析了 ants 的源码,见 ants 源码赏析。在写介绍 ants 的文章和深刻浏览源码过程中,网上的材料提及 Go 语言中 goroutine 池的实现,时常会带上 tunny 这个库。于是,我又去钻研了 tunny 的源码,产出一篇文章 Go 每日一库之 tunny。

在浏览 tunny 源码时,我发现有个办法的实现有些问题。我也在 Go 每日一库之 tunny 中也指出了:

原理

咱们晓得 slice 构造中有一个指向数组的指针。假如一开始 tunny 中有 5 个 worker,示意图如下:

数组中每个元素都是一个指针,指向一个 worker 构造。而后咱们应用 s := s[:4] 缩容了,进变成了上面这样:

当初最初一个元素无奈通过切片拜访了,然而又被底层数组援用着,无奈被 Go 运行时的 gc 清理掉,360 软件管家都不行。这就有内存透露了。尽管这个透露并不重大,一是因为量不可能很大,因为 worker 数量无限,二是下次扩容后地位被笼罩就能够开释原 worker 了(因为没有援用它的指针了)。

ants源码中也有相似的操作,然而会将缩容掉的元素置为 nil。例如worker_stack.go 中的 reset() 办法:

func (wq *workerStack) reset() {for i := 0; i < wq.len(); i++ {wq.items[i].task <- nil
    wq.items[i] = nil
  }
  wq.items = wq.items[:0]
}

PR

确定了问题。我先 fork 了 tunny 的仓库。点击 fork 按钮:

而后将 fork 后的我本人的仓库下载:

$ git clone git@github.com:darjun/tunny.git

批改代码,commit,push 到我的近程仓库。上面是我所做的改变:

而后去 tunny 源仓库,点击 Pull Request 按钮。而后点击右侧的 New pull request 按钮:

新建一个 PR,而后点击compare across forks,抉择我的 fork:

抉择我做批改的那次提交,而后填写信息,提交,因为我曾经提交了 PR。这次比拟就没有差别了。

而后期待作者合并。一天后,作者合并了这次批改:

总结

GitHub 提交 PR 并不难,大到新增个性,小到一个拼写错误,都能够提 PR。置信不少人都据说过,Linus Torvalds 亲自合并了一个来自 11 岁小孩提交的对于 Linux 源码正文中拼写错误的 PR。

GitHub 上 star 很多的我的项目并非完满,必定也有很多值得改良的中央。所以浏览源码时须要带有肯定的狐疑精力,不要把什么奉为圭臬。

大家如果发现好玩、好用的 Go 语言库,欢送到 Go 每日一库 GitHub 上提交 issue😄

参考

  1. tunny GitHub:github.com/Jeffail/tunny
  2. ants GitHub:github.com/panjf2000/ants
  3. Go 每日一库 GitHub:https://github.com/darjun/go-daily-lib

我的博客:https://darjun.github.io

欢送关注我的微信公众号【GoUpUp】,独特学习,一起提高~

正文完
 0