Golang:互斥锁持有时间过长后出现恐慌

我试图弄清楚是什么让我的程序挂起,我的大部分锁不应该超过 200 毫秒。(实际上要少得多!)


我想创建两个新函数 (Lock()和Unlock()),以便 Lock 将有一个计时器,如果 Lock 已被持有超过 200 毫秒,该计时器将发生恐慌。


这是我目前的尝试,但它不起作用,有什么提示吗?


type ShardKV struct {

  lockChan chan bool

}


func (kv *App) lock(reason string) {

    kv.mu.Lock()


    f := func () {

        fmt.Println("PANIC: ms passed")

        select {

        case <- kv.lockChan:

            //

        default:

            panic("PANIC: " + reason)

        }

  }

    time.AfterFunc(time.Second * 10, f)

}


func (kv *App) unlock(reason string) {

    kv.lockChan <- true

    kv.mu.Unlock()

}


HUWWW
浏览 257回答 3
3回答

森栏

您需要使用的返回值time.AfterFunc。这是一个工作示例:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "sync"&nbsp; &nbsp; "time")type Foo struct {&nbsp; &nbsp; m sync.Mutex&nbsp; &nbsp; timer *time.Timer}func (f *Foo) lock() {&nbsp; &nbsp; f.m.Lock()&nbsp; &nbsp; f.timer = time.AfterFunc(3 * time.Second, func() {&nbsp; &nbsp; &nbsp; &nbsp; panic("Too long!")&nbsp; &nbsp; })}func (f *Foo) unlock() {&nbsp; &nbsp; f.timer.Stop()&nbsp; &nbsp; f.m.Unlock()}func main() {&nbsp; &nbsp; foo := &Foo{&nbsp; &nbsp; &nbsp; &nbsp; sync.Mutex{},&nbsp; &nbsp; &nbsp; &nbsp; &time.Timer{},&nbsp; &nbsp; }&nbsp; &nbsp; foo.lock()&nbsp; &nbsp; // Uncomment this to see the difference&nbsp; &nbsp; //time.Sleep(5 * time.Second)&nbsp; &nbsp; foo.unlock()&nbsp; &nbsp; fmt.Println("Success!")}游乐场链接:https : //play.golang.org/p/WVPp0_Iqlb

隔江千里

您说过如果锁定已保持 200 毫秒,您希望您的代码恐慌,但您给了计时器 10 秒的等待时间。这只会在恐慌之前等待 10 秒而不是 200 秒。我已经尝试过您的代码以下列方式对其进行编辑:package mainimport (&nbsp; &nbsp; "sync"&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "time")type App struct {&nbsp; &nbsp; mu sync.Mutex&nbsp; &nbsp; lockChan chan bool}func (kv *App) lock(reason string) {&nbsp; &nbsp; kv.mu.Lock()&nbsp; &nbsp; f := func () {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("PANIC: ms passed")&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <- kv.lockChan:&nbsp; &nbsp; &nbsp; &nbsp; //&nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; panic("PANIC: " + reason)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; time.AfterFunc(time.Millisecond * 200, f)}func (kv *App) unlock(reason string) {&nbsp; &nbsp; kv.lockChan <- true&nbsp; &nbsp; kv.mu.Unlock()}func NewApp() *App {&nbsp; &nbsp; app := App{}&nbsp; &nbsp; app.lockChan = make(chan bool)&nbsp; &nbsp; return &app}func main() {&nbsp; &nbsp; app := NewApp()&nbsp; &nbsp; app.lock("locking")&nbsp; &nbsp; time.Sleep(time.Millisecond * 300)}上面的代码工作得很好并且很恐慌。如果将 main 函数中的持续时间设置为200 * time.Millisecond,它不会恐慌并停止运行。

白衣非少年

您的 lock 函数在调用包含 select 语句的 f 函数之前等待 10 秒,实现您想要做的更简单的方法可能是:func (kv *App) lock(reason string) {&nbsp; &nbsp; kv.mu.Lock()&nbsp; &nbsp; select {&nbsp; &nbsp; case <- kv.lockChan:&nbsp; &nbsp; &nbsp; &nbsp; //&nbsp; &nbsp; case <-time.After(time.Second * 10):&nbsp; &nbsp; &nbsp; &nbsp; panic("PANIC: " + reason)&nbsp; &nbsp; }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go