Go语言学习 Day04 Summary

本文介绍了Go语言中通道(Channels)的核心概念和用法,包括无缓冲通道的同步特性,通过缓冲通道实现数据传递,使用通道进行同步以等待goroutine完成,以及利用选择器(Select)等待多个通道操作。这些机制是Go语言并发编程的关键工具。
摘要由CSDN通过智能技术生成

1. Channels

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

 Create a new channel with make(chan val-type). Channels are typed by the values they convey.

Send a value into a channel using the channel <- syntax.

The <-channel syntax receives a value from the channel.

When we run the program the "ping" message is successfully passed from one goroutine to another via our channel.

By default sends and receives block until both the sender and receiver are ready. This property allowed us to wait at the end of our program for the "ping" message without having to use any other synchronization.

[maxwell@oracle-db-19c Day04]$ vim channels.go   
[maxwell@oracle-db-19c Day04]$ cat channels.go   
package main

import "fmt"

func main(){
   messages := make(chan string)

   go func() {messages <- "ping"}()


   msg := <-messages
   fmt.Println(msg)
}
[maxwell@oracle-db-19c Day04]$ go run channels.go
ping
[maxwell@oracle-db-19c Day04]$ 

2.Channel Buffering

By default channels are unbuffered, meaning that they will only accept sends (chan <-) if there is a corresponding receive (<- chan) ready to receive the sent value. Buffered channels accept a limited number of values without a corresponding receiver for those values.

[maxwell@oracle-db-19c Day04]$ vim channelbuffering.go
[maxwell@oracle-db-19c Day04]$ cat channelbuffering.go 
package main

import "fmt"

func main(){
    messages := make(chan string, 2)
    messages <- "Buffered"
    messages <- "channel"

    fmt.Println(<-messages)
    fmt.Println(<-messages)
}

[maxwell@oracle-db-19c Day04]$ go run channelbuffering.go
Buffered
channel
[maxwell@oracle-db-19c Day04]$ 

3. Channel Synchronization

We can use channels to synchronize execution across goroutines. Here’s an example of using a blocking receive to wait for a goroutine to finish. When waiting for multiple goroutines to finish, you may prefer to use a WaitGroup.

[maxwell@oracle-db-19c Day04]$ vim channelsynchronization.go
[maxwell@oracle-db-19c Day04]$ cat channelsynchronization.go 
package main

import (
     "fmt"
     "time"
)

func worker(done chan bool) {
    fmt.Print("working...")
    time.Sleep(time.Second)
    fmt.Println("Done")

    done <- true

}

func main() {

    done := make(chan bool, 1)
    go worker(done)

    <-done
}
[maxwell@oracle-db-19c Day04]$ go run channelsynchronization.go
working...Done
[maxwell@oracle-db-19c Day04]$ 

4.Channel Directions

When using channels as function parameters, you can specify if a channel is meant to only send or receive values. This specificity increases the type-safety of the program.

This ping function only accepts a channel for sending values. It would be a compile-time error to try to receive on this channel.

The pong function accepts one channel for receives (pings) and a second for sends (pongs).

[maxwell@oracle-db-19c Day04]$ vim channeldirections.go 
[maxwell@oracle-db-19c Day04]$ cat channeldirections.go 
package main

import "fmt"

func ping(pings chan<- string, msg string){
   pings <- msg
}

func pong(pings <-chan string, pongs chan<- string){
   msg := <-pings
   pongs <- msg
}


func main() {
    pings := make(chan string, 1)
    pongs := make(chan string, 1)
    ping(pings, "passed message")
    pong(pings, pongs)
    fmt.Println(<-pongs)
}
[maxwell@oracle-db-19c Day04]$ go run channeldirections.go
passed message
[maxwell@oracle-db-19c Day04]$ 

5.Select

Go’s select lets you wait on multiple channel operations. Combining goroutines and channels with select is a powerful feature of Go.

Each channel will receive a value after some amount of time, to simulate e.g. blocking RPC operations executing in concurrent goroutines.

We’ll use select to await both of these values simultaneously, printing each one as it arrives.

Note that the total execution time is only ~2 seconds since both the 1 and 2 second Sleeps execute concurrently.

[maxwell@oracle-db-19c Day04]$ vim select.go
[maxwell@oracle-db-19c Day04]$ cat select.go
package main

import (
      "fmt"
      "time"
)

func main(){
    c1 := make(chan string)
    c2 := make(chan string)

    go func(){
        time.Sleep(1 * time.Second)
        c1 <- "one"
    }()
    go func(){
       time.Sleep(2 * time.Second)
       c2 <- "two"
    }()

    for i := 0; i< 2; i++ {
        select {
        case msg1 := <-c1:
            fmt.Println("received", msg1)
        case msg2 := <-c2:
            fmt.Println("received", msg2)
        }
    }

}
[maxwell@oracle-db-19c Day04]$ time go run select.go
received one
received two

real    0m2.128s
user    0m0.101s
sys     0m0.086s
[maxwell@oracle-db-19c Day04]$ 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值