Go 學習筆記09.管道 常見操作

管道超時處理

package main

import "time"
import "fmt"

func main() {

    c1 := make(chan string, 1)
    go func() {
        time.Sleep(time.Second * 2)
        c1 <- "result 1"
    }()

    // timeout 1
    select {
    case res := <-c1:
        fmt.Println(res)
    case <-time.After(time.Second * 1):
        fmt.Println("timeout 1")
    }

    // result 2
    c2 := make(chan string, 1)
    go func() {
        time.Sleep(time.Second * 2)
        c2 <- "result 2"
    }()
    select {
    case res := <-c2:
        fmt.Println(res)
    case <-time.After(time.Second * 3):
        fmt.Println("timeout 2")
    }
}
timeout 1
result 2

非阻塞管道操作

package main

import "fmt"

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

    // 非阻塞管道,就是當<-messages中有值,觸發case,沒有存儲值則直接default,沒有時間上的等待
    select {
    case msg := <-messages:
        fmt.Println("received message", msg)
    default:
        fmt.Println("no message received")
    }

    // 一個非阻塞發送的實現方法和上面一樣。
    msg := "hi"
    select {
    case messages <- msg:
        fmt.Println("sent message", msg)
    default:
        fmt.Println("no message sent")
    }

    // default前 也可以有多個case,都沒有值存儲則執行default
    select {
    case msg := <-messages:
        fmt.Println("received message", msg)
    case sig := <-signals:
        fmt.Println("received signal", sig)
    default:
        fmt.Println("no activity")
    }
}
no message received
no message sent
no activity

管道的關閉

package main

import "fmt"


func main() {
    jobs := make(chan int, 5)
    done := make(chan bool)

    go func() {
        for {
            // 如果管道被關閉,並且已經取出所有的值,則more是false
            j, more := <-jobs
            if more {
                fmt.Println("received job", j)
            } else {
                fmt.Println("received all jobs")
                done <- true
                return
            }
        }
    }()

    for j := 1; j <= 3; j++ {
        jobs <- j
        fmt.Println("sent job", j)
    }
    close(jobs)
    fmt.Println("sent all jobs")
    // done 管道只是用來阻塞用的嗎,上一章實踐過的一種同步方法
    <-done
}

管道的遍歷

for range 遍歷

package main

import "fmt"

func main() {

    queue := make(chan string, 2)
    queue <- "one"
    queue <- "two"
    close(queue)

    // for range 遍歷
    for elem := range queue {
        fmt.Println(elem)
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章