2016-06-23 9 views
0

意図的な無限ループを持つコードで作業していますが、そのコードを変更することはできません。そのメソッドについていくつかのテストを書いてみたい(たとえば、適切なタイミングでアクションがトリガーされていることを確認するなど)。しかし、私はルーチンの束を孤立させたくありません。だから私はそのゴルーチンを殺す/中断する方法を見つけようとしている。無限ループ内でメソッドを終了する(golang)

私は信号の後にそれを殺すラッパー関数でラップしようと考えていました。このように(動作しません)。

func wrap(inf func()) func() { 
    return func() { 
    select { 
    case inf(): 
    case <-time.After(5 * time.Second): 
    } 
    } 
} 

func main() { 
    go wrap(inf())() 
    // do things 
} 

私が考えることができるすべてのバリエーションは実際には機能しません。私はinfを、(決して呼び出されることのない)チャネルに書き込む関数、またはreturn文を持つ関数にラップすることを考えていました。そしてそれからselectが読むことができます。問題はあなたがそれを立ち上げなければならないことです。あなたがこのルーチンでそれを行うなら、あなたはselectに決して行きません。あなたが別のルーチンでそれを行うなら、あなたはちょうど問題を悪化させました。

私はそのルーチンを殺すことができる方法はありますか?

(はい - 私はむしろ無限ループのコードを変更するだろうが、ここにいない缶)

答えて

3

あなたはループのコードを変更できない場合は、ループを殺すことはできません。 Goは意図的に設計されており、goroutineの外側からゴルーチンを殺す方法はなく、プログラム自体を実際に終了させることはできません。

ループ自体を変更できる場合、ルーチンを終了させる典型的な方法は、ゴルーチンに終了チャネルを提供し、ループを終了するようにそのチャネルを閉じる(または送信する)ことです。例:

quitCh := make(chan struct{}) 
go func() { 
    for { 
     select { 
     case <-quitCh: 
      return 
     // other cases to handle what you need to do 
     } 
    } 
}() 

// Once you're done 
close(quitCh) // goroutine exits 

しかし、ループ自体にその閉鎖動作をコーディングするいくつかの方法なしに、特にそのゴルーチンを殺すか、それ(内ループを終了する(私の知る限り)方法はありません、あなたはパニックを誘発することができない限り、それはひどいその問題を処理する方法です)

関連する問題