Go学習のチャンネルまとめ

4437 ワード

ChannelはGoのコアタイプで、パイプと見なし、コアユニットを並列に接続することでデータを送信または受信して通信することができます.

を選択します。


Tは任意の種類を表す
  • 双方向:chan T
  • 一方向送信のみ:chan
  • 一方向のみ:

  • 一方的なchannelは、make(chan , chanを するだけでなく、 のように することができます.
    func main() {
          channel := make(chan int, 10)
            convert(channel)
    }
    func convert(channel chan
    convert , channel chanであれば、 も もできるのに、なぜ chanが するのか. の の1つは、 の です. えば、 システムでは、ページの をキャプチャし、プロセスbに するプロセスaがあります.プロセスaは chanで です.

    Blocking


    デフォルトでは、 chanまたは chanは、 が できるまでブロックされます.この は、 されたロックや を することなくgororutineで するために することができる.
    の ではx, y := channel 。
    func bufferChannel() {
        channel := make(chan int)
        i := 0
        go func(i int) {
        fmt.Printf("start goroutine %d
    ", i)① channel

    は の りです.
    start goroutine 0
    sleep 2 second
    got  0
    send 0 to channel
    go funcが①まで された は②を し けるのではなく、③の が するのを ってから②を していることがわかる.
    もし、 はここでブロックしたくないならば、 は データをchannel goroutineの に いて、 が ができたら、channelの で でどのように するかを って、ここでもう つの buffered channelに しています.

    buffered channel


    プログラムを します
    func bufferChannel() {
        channel := make(chan int, 1) //  
        i := 0
        go func(i int) {
            fmt.Printf("start goroutine %d
    ", i)① channel

    start goroutine 0
    send 0 to channel
    sleep 2 second
    got  0
    channelが①を した に②を していることを し、③の が わるのを っていない.これがbuffered channelの である.
    makeの 、 の2つのパラメータ、つまりchanのバッファサイズを するだけでいいです.
    の から かるように, は3の ,すなわちgo funcを いてきた.
    for {
        value 

    もっと な はありますか?

    for … range


    それとも のプログラムですか、for...rangeを って します.
    func bufferChannel() {
       channel := make(chan int, 1)
       i := 0
       go func(i int) {
          fmt.Printf("start goroutine %d
    ", i) channel

    これで chan , goroutine chan , のデータを ることができますが、 たちは に します.ああ、このプログラムはどうして まらないのですか.channelで された はChannelで された であり、channelが じられるまで されるので、range channelでデータを した 、goroutineを じてみましょう. は、channelは われません.
    func bufferChannel() {
       channel := make(chan int, 1)
       i := 0
       go func(i int) {
          fmt.Printf("start goroutine %d
    ", i) channel

    これにより、プログラム が に するので、time.Sleep(2 * time.Second)を するときは が です.rangeが じなければ、channelはずっとここに まっています.

    select


    の で うのはずっと1つのrangeだけの 、 はどのようにするべきで、2つのchannelあるいはそれ のchannelが って、 はどのようにするべきで、ここでgoの の のchannelを して、 のプログラムを にとります
    func example() {
        tick := time.Tick(time.Second)
        after := time.After(3 * time.Second)
        for {
            select {
            case 
    selectはgoのtimeパケットが するタイマの であり、time.Tickを し、 された でchannelにデータを し、channelは このchannelにデータを する.time.Tick(time.Second)はgoのtimeパケットが するタイマの であり、time.Afterを し、 された にchannelにデータを し、channelは3 s にこのchannelにデータを する.
    come into default
    come into default
    tick 1 second
    come into default
    come into default
    tick 1 second
    come into default
    come into default
    tick 1 second
    after 3 second
    time.After(3 * time.Second)は、ブロックされていないselectを し、 channelの を することによって、caseのブロックによる の ブロックを することができることが かる.
    たちは さな を けて、 に じたchannelchannelの に れて してみましょう.
    func example() {
        tick := time.Tick(time.Second)
        after := time.After(3 * time.Second)
        channel := make(chan int, 1)
        go func() {
            channel 

    .
    .
    .
    .
    got 0
    got 0
    got 0
    got 0
    got 0
    after 3 second

    まさに の で、 いにも3 sを して に して、それではcaseの 、このchannelが したかどうかを することができますか?
    func example() {
        tick := time.Tick(time.Second)
        after := time.After(3 * time.Second)
        channel := make(chan int, 1)
        go func() {
            channel 

    come into default
    got 1
    channel is closed
    tick 1 second
    channel is closed
    channel is closed
    after 3 second

    よりselect じるかどうか、okはtrueで、channelが であることを して、さもなくば、channelは じます