基础七

说明

  • 本章主要说明Go语言中的线程相关

  • 下面的示例代码来自于这里

线程

创建

  • goroutine 是由 Go 运行时环境管理的轻量级线程,使用go关键字来开启一个新的 goroutine 执行
go f(x, y, z)
  • 下面是一个具体使用线程的示例
package main

import (
    "log"
    "time"
)

func say(s string) {
    for i := 0; i < 5; i++ {
        time.Sleep(1000 * time.Millisecond)
        log.Println(s)
    }
}

func main() {
    go say("hello")
    say("world")

}

管道

创建

  • channel 是有类型的管道,可以用 channel 操作符 <- 对其发送或者接收值
ch <- v    // 将 v 送入 channel ch。
v := <-ch  // 从 ch 接收,并且赋值给 v。
  • 创建一个channel对象可以使用如下方法
ch := make(chan int)

缓冲区

  • channel可以设置缓冲区
package main

import "fmt"

func main() {
    c := make(chan int, 1)//缓冲区大小为1
    c <- 1
    fmt.Println(<-c)
    c <- 2
    fmt.Println(<-c)
}

关闭

  • 可以调用close方法来关闭一个 channel,close方法应与发送者位于同一线程中
close(c)
  • 接收者可以通过赋值语句的第二参数来判断channel 是否被关闭:当没有值可以接收并且 channel 已经被关闭
v, ok := <-ch

此时 ok 的值为false

分支

分支选择

  • select 语句可以使一个 goroutine 在多个通讯操作上等待
package main

import "fmt"

func fibonacci(c, quit chan int) {
    x, y := 0, 1
    for {
        select {
        case c <- x:
            x, y = y, x+y
        case <-quit:
            fmt.Println("quit")
            return
        }
    }
}

func main() {
    c := make(chan int)
    quit := make(chan int)
    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println(<-c)
        }
        quit <- 0
    }()
    fibonacci(c, quit)
}
  • 其中 case 的条件必须是取值、赋值、或者取值的断言

默认选择

  • 当 select 中的其他条件分支都没有准备好的时候,default 分支会被执行
package main

import (
    "fmt"
    "time"
)

func main() {
    tick := time.Tick(100 * time.Millisecond)
    boom := time.After(500 * time.Millisecond)
    for {
        select {
        case <-tick:
            fmt.Println("tick.")
        case <-boom:
            fmt.Println("BOOM!")
            return
        default:
            fmt.Println("    .")
            time.Sleep(50 * time.Millisecond)
        }
    }
}

  • 默认情况下,在另一端准备好之前,发送和接收都会阻塞。这使得 goroutine 可以在没有明确的锁或静态变量的情况下进行同步

  • 只有发送者才能关闭 channel,而不是接收者。向一个已经关闭的 channel 发送数据会引起 panic

  • channel 与文件不同;通常情况下无需关闭它们。只有在需要告诉接收者没有更多的数据的时候才有必要进行关闭,例如中断一个 range

package main

import (
    "fmt"
)

func fibonacci( c chan int) {
    x, y := 0, 1
    for i := 0; i < cap(c); i++ {
        c <- x
        x, y = y, x+y
    }
    close(c)
}

func main() {
    c := make(chan int, 10)
    go fibonacci( c)
    for i := range c {
        fmt.Println(i)
    }
    fmt.Println(i, ok)//ok为false
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值