golang协程,管道,Select 的基础讲解

以下是对 Go 语言中协程、管道和 select 的基础讲解:

协程(Goroutine)

协程是 Go 语言中轻量级的并发执行单元。它允许在一个程序中同时执行多个函数,并且这些函数的执行可以相互独立和并发进行。协程的创建成本很低,使得并发编程变得简单和高效。

管道(Channel)

管道是用于在不同的协程之间进行通信和同步的机制。它可以看作是一个先进先出(FIFO)的队列,数据可以在发送方(通过 <- 操作符发送)和接收方(通过 <- 操作符接收)之间传递。

管道有两种类型:无缓冲管道和有缓冲管道。

无缓冲管道:发送和接收操作必须同时准备好,否则会导致阻塞。

有缓冲管道:可以存储一定数量的数据,当缓冲区未满时,发送操作不会阻塞;当缓冲区为空时,接收操作会阻塞。

Select 语句

select 语句用于监听多个管道的操作。它类似于 switch 语句,但用于处理多个管道的通信情况。

select 会阻塞直到其中一个分支可以执行,如果多个分支都可以执行,会随机选择一个执行。

package main

import (
    "fmt"
    "time"
)

func main() {
    // 创建无缓冲管道
    ch1 := make(chan int)
    ch2 := make(chan string)

    // 启动协程向管道发送数据
    go func() {
        time.Sleep(2 * time.Second)
        ch1 <- 10
    }()

    go func() {
        time.Sleep(3 * time.Second)
        ch2 <- "Hello"
    }()

    // 使用 select 监听管道
    select {
    case value := <-ch1:
        fmt.Println("Received from ch1:", value)
    case value := <-ch2:
        fmt.Println("Received from ch2:", value)
    }
}

在上述示例中,select 会阻塞等待 ch1 或 ch2 中有数据可读,当其中一个管道有数据时,对应的分支会被执行。

以下是一个示例,展示如何在 go func 中的 for 循环中向管道发送数据,并在 select 中持续获取这些数据:

package main

import (
    "fmt"
    "time"
)

func main() {
    // 创建一个管道
    ch := make(chan int)

    // 启动一个协程,在 for 循环中向管道发送数据
    go func() {
        for i := 0; i < 10; i++ {
            ch <- i
            time.Sleep(500 * time.Millisecond)
        }
        close(ch)
    }()

    // 使用 select 持续获取管道值
    for {
        select {
        case value, ok := <-ch:
            if ok {
                fmt.Println("Received:", value)
            } else {
                // 管道已关闭,退出循环
                return
            }
        default:
            // 暂时没有数据可获取,执行其他非阻塞操作或等待
            fmt.Println("No data available")
            time.Sleep(1 * time.Second)
        }
    }
}

在上述代码中,在 go func 里的 for 循环中不断向管道发送数据。在 main 函数的主循环中,使用 select 尝试从管道接收数据。如果有数据,就进行处理;如果暂时没有数据,就执行 default 分支中的操作。当管道关闭时,通过判断接收值的第二个返回值 ok 来得知,并退出循环。

  • 24
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
协程是轻量级的线程,可以在同一个程序中并发地执行多个任务。通过使用协程,我们可以更有效地利用计算资源并实现并发编程。而管道是用于在协程之间传递数据的通信机制。在Go语言中,我们可以使用管道来实现协程之间的同步和通信。 在Go语言中,我们可以通过以下步骤来使用协程管道: 1. 使用关键字"go"来创建一个协程,让其并发执行一个函数或方法。 2. 使用"make"函数来创建一个管道,并指定其元素类型和容量。管道可以是有缓冲的(指定了容量)或者无缓冲的(未指定容量)。 3. 在协程中,使用"<-"操作符将数据发送到管道中,或者从管道中接收数据。 4. 如果管道是无缓冲的,发送操作和接收操作会导致发送方和接收方都会阻塞,直到对应的操作完成。这种情况下,协程之间的通信是同步的。 5. 如果管道是有缓冲的,发送操作只有在管道已满时才会阻塞,接收操作只有在管道为空时才会阻塞。这种情况下,协程之间的通信是异步的。 下面是一个示例代码来演示协程管道的使用: ```go package main import ( "fmt" ) func worker(id int, jobs <-chan int, results chan<- int) { for j := range jobs { fmt.Println("worker", id, "processing job", j) results <- j * 2 } } func main() { jobs := make(chan int, 5) results := make(chan int, 5) // 创建3个协程来并发执行任务 for w := 1; w <= 3; w++ { go worker(w, jobs, results) } // 发送5个任务到管道中 for j := 1; j <= 5; j++ { jobs <- j } close(jobs) // 从结果管道中接收并打印结果 for r := 1; r <= 5; r++ { fmt.Println(<-results) } } ``` 在这个示例中,我们创建了一个有缓冲的"jobs"管道和一个有缓冲的"results"管道。然后,我们创建了3个协程来并发执行任务。每个协程从"jobs"管道中接收任务,处理任务后将结果发送到"results"管道中。最后,主函数从"results"管道中接收并打印结果。 希望这个示例能够帮助你理解如何在Go语言中使用协程管道
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值