2016-08-25 4 views
-1

bestpractice私はゴルーチンがある生み出されたことを確認する方法についての基本的な理解に問題を持っている長期実行中のプロセスのコンテキストで適切に「閉じました」。私はその話題に関する話を見て、ベストプラクティスについて読んでいました。私の質問を理解するためには、ビデオ "高度な同時並行パターン"を参照してください。確保ゴルーチンのクリーンアップは、

マシン上でコードを実行する場合は、環境変数GOTRACEBACK=allをエクスポートして、パニック後にルーチン状態を見ることができます。

私はここで元の例のコードを置く:naive(それが行く遊び場で実行しない、時間の文が使用されているbacause私は推測するコードをコピーし、それをローカルに実行してください。)

の結果を実行後のナイーブな実装のパニックは、長い実行中のプロセスのために特に悪いシステム、上のダングリングゴルーチンを残すの根本的な問題を示してい

panic: show me the stacks goroutine 1 [running]: panic(0x48a680, 0xc4201d8480) /usr/lib/go/src/runtime/panic.go:500 +0x1a1 main.main() /home/flx/workspace/go/go-rps/playground/ball-naive.go:18 +0x16b goroutine 5 [chan receive]: main.player(0x4a4ec4, 0x2, 0xc42006a060) /home/flx/workspace/go/go-rps/playground/ball-naive.go:23 +0x61 created by main.main /home/flx/workspace/go/go-rps/playground/ball-naive.go:13 +0x76 goroutine 6 [chan receive]: main.player(0x4a4ec6, 0x2, 0xc42006a060) /home/flx/workspace/go/go-rps/playground/ball-naive.go:23 +0x61 created by main.main /home/flx/workspace/go/go-rps/playground/ball-naive.go:14 +0xad exit status 2

です。 (再び、遊び場、原因「プロセス上で実行可能ではないが、時間がかかりすぎる

for-select with default

generator pattern with quit channel

は、だから私の個人的な理解のために私はここで見つけることには、2つのもう少し洗練されたバリエーションを試してみました「)

最初の溶液もゴルーチン実行速度に応じて、実行されるステップで非決定論に至る、様々な理由のためにフィッティングされていません。

今、私は思った - と、ここで最後に質問が来ます! - 終了チャネルを使用した2番目のソリューションは、終了する前にシステムからすべての実行トレースを排除するのに適していると考えられます。とにかく、「時々」プログラムがあまりにも速く終了し、パニックが実行可能な、まだシステムに存在する追加のゴルーチンを報告します。パニック出力:

panic: show me the stacks goroutine 1 [running]: panic(0x48d8e0, 0xc4201e27c0) /usr/lib/go/src/runtime/panic.go:500 +0x1a1 main.main() /home/flx/workspace/go/go-rps/playground/ball-perfect.go:20 +0x1a9 goroutine 20 [runnable]: main.player.func1(0xc420070060, 0x4a8986, 0x2, 0xc420070120) /home/flx/workspace/go/go-rps/playground/ball-perfect.go:27 +0x211 created by main.player /home/flx/workspace/go/go-rps/playground/ball-perfect.go:36 +0x7f exit status 2

私の質問は:、右起こるべきではありませんこと?私はパニックに踏み込む前に、クリーンアップ状態で終了チャネルを使用します。

私はここで安全なクリーンアップ動作を実現するための最後の試みでした: artificial wait time for runnables to close

をとにかく、そのソリューションは、右感じていないと、同様ランナブルを大量に適用できないかもしれませんか?

は何が正しいクリーンアップを確保するために推奨される最も慣用的なパターンでしょうか?お時間を

おかげ

+0

私はこの例題がどのように「プログラムが実行終了した後にシステム上にゴルーチンが舞っているか」を実証しています。ゴルーチンはGo実行時のコンセプトであり、プログラムの実行が終了すると解体されます。あなたが見ているものは、ティアダウンがまだ起こっている間に出力されます。この前にそれらがクリーンアップされた場合、ランタイムは何が起こったのかを報告できませんでした。それとも、あなたが言っていることとは完全に離れていますか? –

+0

単純な例のルーチンは、ボールを待って共有チャネルでブロックしているため、終了できません。ビデオの重要なビットは、〜4.40分〜5.10分です。プログラム自体は終了しますが、ぶら下がったルーチンが残っています。 – flx

+0

私はお詫び申し上げます - 私はあなたが長時間実行されているプロセスのコンテキストで話していることを認識していませんでした。実行中のプロセスが実際に終了したわけではありません。 –

答えて

0

あなたが出力にだまされています。あなたの「チャンネルを終了して発電機のパターンは、」完全に正常に動作し、実際に2つのゴルーチンが正しく終了しです。あなたはあまりにも早くパニックので

あなたはトレースでそれらを参照してください。覚えておいてください:メインと同時に実行するgoroutineが必要です。メインは、終了チャネルで信号を送ることによって、これらのゴルーチンを「停止」します。18行目と19行目のこれらの2つの送信の後、32行目の2つの受信が行われました。それ以上は何もない!あなたはまだ3つのゴルーチンを持っています:メインは19から20行の間にあり、プレイヤーのゴルーチンは32と33の間です。もしメインのパニックがプレイヤーのリターンの前に起これば、プレーヤーのゴルーチンはまだそこにあり、パニックスタックトレース。これらのゴルーチンは、スケジューラだけが33行目のリターンを実行する時間があれば、数ミリ秒後に終了していました(パニックでそれを殺害したわけではありません)。

これは、ここで一ヶ月に一度尋ねられる "同時発生するゴルーチンが動作するのを早期に知るための主要な目的"の問題です。あなたは仕事をしているconcorrentのgoroutinesを見ますが、すべて作品ではありません。恐怖の前に2ミリ秒寝ると、あなたのプレーヤーのゴルーチンにはリターンを実行する時間があり、すべてが正常です。

関連する問題