2016-05-02 9 views
0

私のプログラムがハングアップしていることを理解しようとしていますが、ロックのほとんどは200ミリ秒以上保持してはいけません。Golang:ミューテックスロックが長すぎるとパニックになった

2つの新しい関数(Lock()Unlock())を作成して、ロックが200ミリ秒以上ロックされているとパニックするタイマーを持つようにしたいと思います。

これは私の現在の試みですが、ヒントはありません。

func (kv *App) lock(reason string) { 
    kv.mu.Lock() 
    select { 
    case <- kv.lockChan: 
     // 
    case <-time.After(time.Second * 10): 
     panic("PANIC: " + reason) 
    } 
} 
+0

どのようにチャンネルを作成しますか?このコードを動作させるにはバッファリングする必要があります – creker

+0

あなたのコードは10秒間待っていますが、あなたは200ミリ秒間を意図しています。あなたのコードがうまくいかない理由を述べなかったのですが、これが理由でしょうか? –

答えて

0

あなたのロック機能は、SELECT文を保持しているf関数を呼び出すbefor 10秒間待って、何をしようとする達成するための簡単な方法は、このかもしれません戻り値はtime.AfterFuncです。ここでは実施例である:

package main 

import (
    "fmt" 
    "sync" 
    "time" 
) 

type Foo struct { 
    m sync.Mutex 
    timer *time.Timer 
} 

func (f *Foo) lock() { 
    f.m.Lock() 
    f.timer = time.AfterFunc(3 * time.Second, func() { 
     panic("Too long!") 
    }) 
} 

func (f *Foo) unlock() { 
    f.timer.Stop() 
    f.m.Unlock() 
} 

func main() { 
    foo := &Foo{ 
     sync.Mutex{}, 
     &time.Timer{}, 
    } 

    foo.lock() 

    // Uncomment this to see the difference 
    //time.Sleep(5 * time.Second) 

    foo.unlock() 
    fmt.Println("Success!") 
} 

遊び場リンク:https://play.golang.org/p/WVPp0_Iqlb

+0

これは、OPのコードの試行よりも優れたアプローチです。 *と*はどちらも優れた性能を発揮します。 – evanmcdonnal

+2

コードが間違っています。 OPのロック機能は、ミューテックスをロックし、タイマーを開始して戻ります。タイマーはバックグラウンドで待機し、10秒後にミューテックスのロックが解除されているかどうかを確認します。ロック機能は、10秒間、またはミューテックスのロックが解除されるまでブロックされます。それはOPが望むものではなく、あなたの解決策はより悪いものです。あなたは10秒間ブロックしないで、バックグラウンドで待つ。 – creker

0

あなたがする必要がある:

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() 
} 
+0

@nickこれで問題は解決しますか? –

0

あなたはロックが200ミリ秒のために保留されているが、あなたは、タイマーを待つために10秒を与えた場合、あなたのコードはパニックにしたいと述べています。上記のコード

package main 

import (
    "sync" 
    "fmt" 
    "time" 
) 


type App struct { 
    mu sync.Mutex 
    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.Millisecond * 200, f) 
} 

func (kv *App) unlock(reason string) { 
    kv.lockChan <- true 
    kv.mu.Unlock() 
} 

func NewApp() *App { 
    app := App{} 
    app.lockChan = make(chan bool) 
    return &app 
} 

func main() { 
    app := NewApp() 
    app.lock("locking") 
    time.Sleep(time.Millisecond * 300) 

} 

だけで罰金とパニック作品:これは単に私がそれを次のように編集し、あなたのコードを試してみましたが、200の代わりにはpanic前に10秒間待機します。メイン関数の継続時間を200 * time.Millisecondにすると、パニックに陥ることはなく、実行を停止するだけです。

関連する問題