3 回答
TA贡献1828条经验 获得超4个赞
使用缓冲区大小为 1 的通道作为互斥锁。
l := make(chan struct{}, 1)
锁:
l <- struct{}{}
开锁:
<-l
尝试锁定:
select {
case l <- struct{}{}:
// lock acquired
<-l
default:
// lock not acquired
}
尝试超时:
select {
case l <- struct{}{}:
// lock acquired
<-l
case <-time.After(time.Minute):
// lock not acquired
}
TA贡献1859条经验 获得超6个赞
我想你在这里问了几件不同的事情:
标准库中是否存在此功能?不,它没有。您可能可以在其他地方找到实现 - 这可以使用标准库(例如原子)来实现。
为什么标准库中不存在此功能:您在问题中提到的问题是一个讨论。在 go-nuts 邮件列表上也有几个讨论,有几个 Go 代码开发人员贡献:链接 1,链接 2。通过谷歌搜索很容易找到其他讨论。
我怎样才能设计我的程序,这样我就不需要这个了?
(3) 的答案更加微妙,取决于您的具体问题。你的问题已经说了
可以将它实现为一个工作队列(带有通道和东西),但在那种情况下,衡量和利用所有可用的 CPU 变得更加困难
没有详细说明为什么与检查互斥锁状态相比,使用所有 CPU 会更加困难。
在 Go 中,只要锁定方案变得重要,您通常就需要通道。它不应该更慢,而且应该更易于维护。
TA贡献1812条经验 获得超5个赞
go-lock
除了 Lock 和 Unlock 之外,还实现TryLock
,TryLockWithTimeout
和功能。TryLockWithContext
它提供了控制资源的灵活性。
例子:
package main
import (
"fmt"
"time"
"context"
lock "github.com/viney-shih/go-lock"
)
func main() {
casMut := lock.NewCASMutex()
casMut.Lock()
defer casMut.Unlock()
// TryLock without blocking
fmt.Println("Return", casMut.TryLock()) // Return false
// TryLockWithTimeout without blocking
fmt.Println("Return", casMut.TryLockWithTimeout(50*time.Millisecond)) // Return false
// TryLockWithContext without blocking
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
defer cancel()
fmt.Println("Return", casMut.TryLockWithContext(ctx)) // Return false
// Output:
// Return false
// Return false
// Return false
}
TA贡献1780条经验 获得超3个赞
PMutex 实现 RTryLock(ctx context.Context) 和 TryLock(ctx context.Context)
// ctx - some context
ctx := context.Background()
mx := mfs.PMutex{}
isLocked := mx.TryLock(ctx)
if isLocked {
// DO Something
mx.Unlock()
} else {
// DO Something else
}
- 3 回答
- 0 关注
- 139 浏览
添加回答
举报