DeadlockエラーからGo channelメカニズムを理解する(一)

1734 ワード

Goは他の言語とは異なり、言語レベルから同時サポートされており、Threadライブラリに頼って新しいスレッドを作成する必要はありません.Goのchannelメカニズムは、ロックと同時セキュリティの問題をあまり考慮する必要がありません.channelはgoroutine間のデータストリーム伝送方式を提供する.
今日はよくあるdeadlock errorからchannelの特性について議論したいと思います.
次のプログラムを実行します.
var ch = make(chan int)

func main() {
    ch 

terminalは次のエラーを報告します.
fatal error: all goroutines are asleep - deadlock!

チャネル(チャネル)の概念を振り返ると、概ね、チャネルはgoroutine間で相互にコミュニケーションするパイプであり、チャネル内のデータの流通はgoroutine間のメモリの共有を表す.マクロ的には、チャネルは他の言語のキュー(queue)に似ており、先進的な先出しルールに従っています.
チャネルは、バッファレスチャネル(すなわちunbuffered channel)とバッファ付きチャネル(buffered channel)に分けられる.バッファレスチャネルの場合、デフォルトチャネルの送信メッセージ(send)および受信メッセージ(receive)はブロックされている.言い換えれば、バッファレスチャネルは、メッセージを受信し、メッセージを送信する際にgoroutineが停止状態にある.反対側の準備ができていない限り、goroutineは実行を続行できません.
上のプログラムは明らかなエラーサンプルです.main関数がchに実行されると、すべてのスレッドまたはプロセスがリソースの解放を待っている場合、デッドロックと呼ばれます.
デッドロックは非常に興味深い話題であり、よく見られるデッドロックは大きく以下のいくつかの種類に分けられる:i.単一goroutineでのみチャネルを操作し、例は上述の通りである.ii. 直列チャネルの中間ループは、以下のように掛けられる.
var ch1 chan int = make(chan int)
var ch2 chan int = make(chan int)

func say(s string) {
    fmt.Println(s)
    ch1 

ch 1はch 2がデータを残すのを待つが、ch 2はデータを発行していないためgoroutineがブロックされ、解決策はch 2にデータを与えることである.
func feedCh2(ch chan int) {
    ch 

iii.非バッファチャネルのペアが現れない:
c, quit := make(chan int), make(chan int)

go func() {
   c 

もちろん、ペアにならないすべての非バッファチャネルがエラーを報告するわけではありません.
func say(ch chan int) {
    ch 

興味深いことに、say関数は待機チャネル受信メッセージを保留しているが、main goroutineはブロックされておらず、main関数が戻った後もプログラムは自動的に終了することができる.
バッファチャネルについては後述するが、ご意見があればご指導ください.
Reference: http://blog.csdn.net/kjfcpua/article/details/18265441
-終わりだ