ホームページ >よくある問題 >Go言語によるチャンネル関連の説明

Go言語によるチャンネル関連の説明

little bottle
little bottle転載
2019-04-09 11:41:123088ブラウズ

CSP モデルは、Go 言語のスレッド通信に使用されます (正確には、軽量スレッドのゴルーチン間の通信です)。 CSP モデルはアクター モデルに似ており、同時に実行される独立したエンティティで構成されており、エンティティはメッセージを送信して通信します。

1. アクター モデルと CSP モデルの違い:

アクターは直接通信しますが、CSP はチャネルを通じて通信します。結合度の点では、この 2 つは同じですが、後者はより疎結合であるという違いがあります。
主な違いは、CSP モデルでは、メッセージの送信者と受信者がチャネルを通じて疎結合されていることです。送信者はどの受信者がメッセージを消費したかを知らず、受信者はどの送信者がメッセージを送信したかを知りません。 。アクター モデルでは、アクターは自身の状態に基づいてどの受信メッセージを処理するかを選択できるため、自律性と制御性が向上します。
Go 言語のプロセスをブロックしないようにするには、プログラマはさまざまな受信メッセージをチェックして、正しい順序を予測して確認する必要があります。 CSP の利点は、Channel がメッセージをバッファリングする必要がないのに対し、Actor は理論的にはメッセージ バッファとしてサイズ無制限のメールボックスを必要とすることです。
CSP モデルのメッセージ送信者は、受信者がメッセージを受信する準備ができている場合にのみメッセージを送信できます。対照的に、Actor モデルでのメッセージ パッシングは非同期です。つまり、メッセージの送信と受信を同時に行う必要はなく、受信者がメッセージを受信する準備ができる前に、送信者はメッセージを送信できます。

2. Go Channel の詳細説明
Channel タイプの定義形式は以下のとおりです:

ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .

3 つのタイプの定義が含まれます。オプションの <- はチャネルの方向を表します。方向が指定されていない場合、チャネルは双方向であり、データの受信と送信の両方が可能です。

chan T          // 可以接收和发送类型为 T 的数据
chan<- float64  // 只可以用来发送 float64 类型的数据
<-chan int      // 只可以用来接收 int 类型的数据

<-常に最初に一番左のタイプと組み合わせます。 (<- 演算子は可能な限り左端の chan に関連付けられます)

c := make(chan bool) //创建一个无缓冲的bool型Channel
c <- x        //向一个Channel发送一个值
<- c          //从一个Channel中接收一个值
x = <- c      //从Channel c接收一个值并将其存储到x中
x, ok = <- c  //从Channel接收一个值,如果channel关闭了或没有数据,那么ok将被置为false

デフォルトでは、チャネルの送信者と受信者は、相手が送受信の準備ができるまでブロックされます。これにより、Go 言語はロックやその他の必要がなくなります。条件は自然に同時実行をサポートします。
make を使用してチャネルを初期化すると、容量を設定できます。

make(chan int, 100) #//创建一个有缓冲的int型Channel

Capacity (容量) は、チャネルが収容できる要素の最大数を表し、チャネルのキャッシュのサイズを表します。
容量が設定されていない場合、または容量が 0 に設定されている場合は、チャネルにキャッシュがないことを意味します。
追加の同期措置を考慮することなく、複数のゴルーチン内のチャネルとの間でデータを送受信できます。
チャネルは先入れ先出し (FIFO) キューとして使用でき、受信データと送信データの順序は一致します。
バッファリングのないチャネルは通信と同期の両方の特性を備えており、同時開発で非常に人気があります。

// _Channels_ are the pipes that connect concurrent
// goroutines. You can send values into channels from one
// goroutine and receive those values into another
// goroutine.

package main

import "fmt"

func main() {

    // Create a new channel with `make(chan val-type)`.
    // Channels are typed by the values they convey.
    messages := make(chan string)

    // _Send_ a value into a channel using the `channel <-`
    // syntax. Here we send `"ping"`  to the `messages`
    // channel we made above, from a new goroutine.
    go func() { messages <- "ping" }()

    // The `<-channel` syntax _receives_ a value from the
    // channel. Here we&#39;ll receive the `"ping"` message
    // we sent above and print it out.
    msg := <-messages
    fmt.Println(msg)
}

ここでは、バッファリングされていない文字列型のチャネルを作成し、ゴルーチンで channel<- を使用してこのチャネルに「ping」を渡します。 <- チャネルはこの値を受け取り、main 関数で出力します。実際、ここでは Channel を使ってゴルーチンからメインのゴルーチンに「ping」メッセージを静かに転送し、スレッド間(正確にはゴルーチン間)の通信を実現しています。
チャネルの送信側と受信側は、相手側が送信または受信の準備ができるまでブロックされるため、他の同期操作を必要とせずに、プログラムの最後に「ping」メッセージを待つことができます。
別の例を見てみましょう: ユーザー定義のゴルーチンが操作を完了すると、メインのゴルーチンに通知します:

// We can use channels to synchronize execution// across goroutines. Here&#39;s an example of using a// blocking receive to wait for a goroutine to finish.package mainimport "fmt"import "time"// This is the function we&#39;ll run in a goroutine. The// `done` channel will be used to notify another// goroutine that this function&#39;s work is done.func worker(done chan bool) {
    fmt.Print("working...")
    time.Sleep(time.Second)
    fmt.Println("done")    // Send a value to notify that we&#39;re done.
    done <- true}func main() {    // Start a worker goroutine, giving it the channel to
    // notify on.
    done := make(chan bool, 1)    go worker(done)    // Block until we receive a notification from the
    // worker on the channel.
    <-done
}

CSP モデルは、Go 言語でのスレッド通信に使用されます (正確には、軽量スレッドのゴルーチン間の通信です)。 CSP モデルはアクター モデルに似ており、同時に実行される独立したエンティティで構成されており、エンティティはメッセージを送信して通信します。

【おすすめコース: Go ビデオチュートリアル

以上がGo言語によるチャンネル関連の説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。