脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Golang - Go1.18 新特性:TryLock 是什么?需要它吗?

Go1.18 新特性:TryLock 是什么?需要它吗?

2021-12-27 23:49polarisxu站长polaris Golang

我们知晓,Go 标准库的 sync/Mutex、RWMutex 实现了 sync/Locker 接口, 提供了 Lock() 和 UnLock() 方法,可以获取锁和释放锁,我们可以方便的使用它来控制对共享资源的并发控制。

Go1.18 新特性:TryLock 是什么?需要它吗?

大家好,我是 polarisxu。

我们知晓,Go 标准库的 sync/Mutex、RWMutex 实现了 sync/Locker 接口, 提供了 Lock() 和 UnLock() 方法,可以获取锁和释放锁,我们可以方便的使用它来控制对共享资源的并发控制。(其他语言,比如 Java 是有类似 TryLock 的功能的)

  1. type Locker interface {
  2. Lock()
  3. Unlock()
  4. }

但是锁被获取后,在未释放之前其他 goroutine 再调用 Lock 则会被阻塞住,这种设计在有些情况下可能不能满足需求。有时我们希望尝试获取锁,如果获取到了则继续执行,如果获取不到,我们也不想阻塞住,而是去调用其它的逻辑,这个时候我们就想要 TryLock 方法:即尝试获取锁,获取不到也不堵塞。

这个需求,2013 年就有人提出,但官方没有采纳。2018 年又有人提出:https://github.com/golang/go/issues/27544,建议增加 TryLock,但没有下文。直到 2021 年 4 月,有人再次提出,同时也给出了标准库中需要的场景:https://github.com/golang/go/issues/45435。

不过,Go Team 的负责人 rsc 提出了反对的意见:

Locks are for protecting invariants. If the lock is held by someone else, there is nothing you can say about the invariant.

TryLock encourages imprecise thinking about locks; it encourages making assumptions about the invariants that may or may not be true. That ends up being its own source of races.

There are definitely locking issues in http2. Adding TryLock would let us paper over them to some extent, but even that would not be a real fix. It would be more like the better your 4-wheel-drive the farther out you get stuck.

I don't believe http2 makes a compelling case for TryLock.

他认为 TryLock 会鼓励设计者对锁进行不精确的思考,这可能最终会成为 race(竞态) 的根源。同时,他认为仅为 http2 提供 TryLock 不值得,希望有更具说服力的案例。

然后大家进行了一些讨论,同时 rsc 给了一个实现,并提到:

sync: add Mutex.TryLock, RWMutex.TryLock, RWMutex.TryRLock

Use of these functions is almost (but not) always a bad idea.

Very rarely they are necessary, and third-party implementations (using a mutex and an atomic word, say) cannot integrate as well with the race detector as implmentations in package sync itself.

也就是现在 Go1.18 中实现的三个方法。不过,rsc 建议,大家尽量别使用它。

可见,最后 rsc 妥协了,因为有人提出了一些实现 TryLock 的代码。就像 neild 说的,虽然大部分时候可能确实不需要 TryLock,但出现各种第三方版本的 TryLock,并非好事,而应该有一个官方的实现。

看看 Mutex.TryLock 官方的实现:https://pkg.go.dev/sync@master#Mutex.TryLock,强调虽然存在正确使用 TryLock 的情况,但很少见。可见官方是勉为其难的添加了它。

关于 TryLock,2017 年鸟窝大佬写过一篇文章, 如何自己实现一个,而且对比了几种实现方式的性能,感兴趣的可以阅读:https://colobu.com/2017/03/09/implement-TryLock-in-Go/。

本文转载自微信公众号「polarisxu」,可以通过以下二维码关注。转载本文请联系polarisxu公众号。

Go1.18 新特性:TryLock 是什么?需要它吗?

原文链接:https://mp.weixin.qq.com/s/NGiBcw0Je-clQd0paAsI9Q

延伸 · 阅读

精彩推荐
  • GolangGolang通脉之数据类型详情

    Golang通脉之数据类型详情

    这篇文章主要介绍了Golang通脉之数据类型,在编程语言中标识符就是定义的具有某种意义的词,比如变量名、常量名、函数名等等,Go语言中标识符允许由...

    4272021-11-24
  • Golanggolang json.Marshal 特殊html字符被转义的解决方法

    golang json.Marshal 特殊html字符被转义的解决方法

    今天小编就为大家分享一篇golang json.Marshal 特殊html字符被转义的解决方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 ...

    李浩的life12792020-05-27
  • Golanggo语言制作端口扫描器

    go语言制作端口扫描器

    本文给大家分享的是使用go语言编写的TCP端口扫描器,可以选择IP范围,扫描的端口,以及多线程,有需要的小伙伴可以参考下。 ...

    脚本之家3642020-04-25
  • Golanggo日志系统logrus显示文件和行号的操作

    go日志系统logrus显示文件和行号的操作

    这篇文章主要介绍了go日志系统logrus显示文件和行号的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    SmallQinYan12302021-02-02
  • Golanggolang的httpserver优雅重启方法详解

    golang的httpserver优雅重启方法详解

    这篇文章主要给大家介绍了关于golang的httpserver优雅重启的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,...

    helight2992020-05-14
  • Golanggolang如何使用struct的tag属性的详细介绍

    golang如何使用struct的tag属性的详细介绍

    这篇文章主要介绍了golang如何使用struct的tag属性的详细介绍,从例子说起,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看...

    Go语言中文网11352020-05-21
  • GolangGolang中Bit数组的实现方式

    Golang中Bit数组的实现方式

    这篇文章主要介绍了Golang中Bit数组的实现方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    天易独尊11682021-06-09
  • Golanggolang 通过ssh代理连接mysql的操作

    golang 通过ssh代理连接mysql的操作

    这篇文章主要介绍了golang 通过ssh代理连接mysql的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    a165861639710342021-03-08