Golang は、高い同時実行性と簡潔な構文で知られる強力に型指定された言語です。その中でも、chan は Golang の一般的な通信方法の 1 つであり、同時プログラミングの実装において重要な部分です。この記事では、Golang における chan の使い方と基本について詳しく見ていきます。
1. chan の概念と機能
Chan は、パイプラインと呼ばれる、Golang のゴルーチン間の通信を実現するための重要な方法です。これは、Golang プログラムで情報を渡すために使用されるスレッドセーフなデータ構造です。 chan は一方向通信と双方向通信を実装でき、データの送受信に使用でき、ゴルーチンの同期にも使用できます。
2. chan の型と使い方
Golang における Chan は、make 関数を使用して作成できる型です。構文は次のとおりです。
ch := make(chan int)
ここで、int はパイプラインで渡されるデータのタイプを表します。 chan を使用するときは、次の点に注意する必要があります。
送信操作と受信操作の両方がブロックされています。送信操作と受信操作が一致する場合、ゴルーチンはこの操作で常にブロックされます。例:
ch := make(chan int) // 发送操作 go func() { ch <- 1 }() // 接收操作 a := <- ch
この例では、int 型のパイプを作成し、送信操作と受信操作をそれぞれ実行しました。送信操作では値 1 をパイプに送信し、受信操作では値をパイプから取り出して変数 a に割り当てます。送信操作と受信操作の両方がブロックされているため、このプログラムは正常に終了する前に、送信操作と受信操作が一致するまで待機します。
close 関数を使用してパイプを閉じることができます。閉じたパイプを再度送信することはできません。例:
ch := make(chan int) // 发送操作 go func() { ch <- 1 close(ch) }() // 循环接收操作 for { if val, ok := <-ch; ok { fmt.Println(val) } else { break } }
この例では、送信操作の後に close 関数を呼び出し、for ループを使用してパイプラインを受信します。受信操作では、デッドロックを防ぐためにパイプラインが閉じられているかどうかを判断するために ok が使用されます。
パイプの方向を設定することでワンウェイチャンを作成できます。例:
ch := make(chan int) // 双向chan // 定义只能发送的单向chan sendCh := make(chan <- int) // 定义只能接收的单向chan recvCh := make(<- chan int) // 发送操作时可以使用单向chan go func() { sendCh <- 1 }() // 接收操作时也可以使用单向chan a := <-recvCh
この例では、make 関数を通じて双方向の chan を作成し、次に make 関数を通じて送信のみと受信のみが可能な一方向の chan を作成します。送信操作と受信操作では、それぞれ sendCh と recvCh を使用します。
select ステートメントは、複数のパイプラインのステータスを同時に監視でき、パイプラインの同時読み取りおよび書き込み操作に使用できます。例:
ch1 := make(chan int) ch2 := make(chan int) // 发送操作 go func() { ch1 <- 1 }() // 使用select语句并发监听多个管道 select { case a := <- ch1: fmt.Println(a) case b := <- ch2: fmt.Println(b) }
この例では、2 つのパイプライン ch1 と ch2 を作成し、ゴルーチンで値 1 を ch1 に送信しました。その後、select ステートメントを使用して 2 つのパイプをリッスンし、最初の値を受け取った case ステートメントが最初に実行されました。
3. chan の基本原理
Golang では、chan は特別なデータ構造に基づいて実装されます。 make 関数を使用して chan を作成すると、実際にはチャネルと呼ばれる、値が nil で長さが 0 のスライスが作成されます。
chan の原理は次のように理解できます。
送信操作を実行すると、送信されるデータは次のようになります。チャネルの下部のスライスに追加されます。チャネルの長さが 0 の場合、追加された要素のインデックスは 0 になります。チャネルの長さが 0 でない場合、追加された要素のインデックスはチャネルの長さになります。
チャネルの長さが容量の上限に達した場合、より大きなスライスがメモリ内に作成され、元のスライスの要素が新しいスライスにコピーされます。したがって、送信操作を実行するときは、メモリ管理とコピーのメカニズムが使用されます。
受信操作を実行すると、追加された最初の要素がチャネルの下部のスライスから取り出されます。スライスに要素がない場合は、要素が使用可能になるまで待機します。チャネルが閉じられている場合、受信操作はすぐにゼロ値を返します。
送信または受信操作を実行するときに、チャネルのスライス長が容量制限に達した場合、またはチャネル内に受信を待機しているデータがある場合、送信するか、十分なスペースまたはデータが利用可能になるまで受信操作がブロックされます。
チャネルを閉じると、チャネルのステータスがクローズに設定され、それ以上データを送信できなくなります。チャネル内に未受信のデータがある場合、チャネル内にデータがなくなるまで受信動作を続行できます。
概要
Golang の Chan は、ゴルーチン間の通信を実現する重要な方法であり、構文の点でも非常に簡潔です。 chan の基本的な使用法と原則をマスターすることは、同時プログラミングにとって非常に重要です。
以上がゴランちゃんの使い方の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。