`

Go channel简单使用

 
阅读更多

channel有点类似于管道,它在goroutine同步与通信中,有着起承转合的作用,同时也是Golang实现CSP模型的关键

package main

func main() {
    senderOnly := make(chan<- int)   // 只能用来发送(管道的入口,只进不出)
    receiverOnly := make(<-chan int) // 只能用来接收(管道的出口,只出不进)
    unbuffer := make(chan int)       // 无缓冲可收发
    buffer := make(chan int, 2)      // 无缓冲可收发
    println(senderOnly, receiverOnly, unbuffer, buffer)
}

以下是channel的一些使用场景

等待goroutine完成

package main

func main() {
    println("start main")
    ch := make(chan bool)
    go func() {
        println("come into goroutine")
        ch <- true
    }()

    println("do something else")
    <-ch
    close(ch)

    println("end main")
}

在playground中运行
打印结果:

start main
do something else
come into goroutine
end main

多个goroutine协同

三个功能不相关的goroutine最后结果要汇总累加到result

package main

func main() {
    println("start main")
    ch := make(chan int)

    var result int
    go func() {
        println("come into goroutine1")
        var r int
        for i := 1; i <= 10; i++ {
            r += i
        }
        ch <- r
    }()

    go func() {
        println("come into goroutine2")
        var r int = 1
        for i := 1; i <= 10; i++ {
            r *= i
        }
        ch <- r
    }()

    go func() {
        println("come into goroutine3")
        ch <- 11
    }()

    for i := 0; i < 3; i++ {
        result += <-ch
    }
    close(ch)
    println("result is:", result)
    println("end main")
}

在playground中运行
其中一组打印结果:

start main
come into goroutine3
come into goroutine2
come into goroutine1
result is: 3628866
end main

Select

两个goroutine无直接关联,但其中一个先达到某一设定条件便退出或超时退出

package main

import "time"

func main() {
    println("start main")
    cond1 := make(chan int)
    cond2 := make(chan uint64)

    go func() {
        for i := 0; ; i++ {
            cond1 <- i
        }
    }()

    go func() {
        var i uint64
        for ; ; i++ {
            cond2 <- i
        }
    }()

    endCond := false
    for endCond != true {
        select {
        case a := <-cond1:
            if a > 99 {
                println("end with cond1")
                endCond = true
            }
        case b := <-cond2:
            if b == 100 {
                println("end with cond2")
                endCond = true
            }
        case <-time.After(time.Microsecond):
            println("end with timeout")
            endCond = true
        }
    }

    println("end main")
}

在playground中运行
其中打印结果有可能是:

start main
end with cond1
end main

也有可能是:

start main
end with timeout
end main

也可能是:

start main
end with cond2
end main

这说明循环100次大概需要1微秒的时间

channel与range

package main

import "fmt"

func main() {
    println("start main")
    ch := make(chan int, 4)
    go func() {
        for i := 0; i < 10; i++ {
            ch <- i
        }
        // 如果不关闭channel,会引发panic
        close(ch)
    }()

    for v := range ch {
        fmt.Println(v)
    }
    println("end main")
}

打印结果为:

start main
0
1
2
3
4
5
6
7
8
9
end main

无缓冲channel

package main

func main() {
    var ch = make(chan int)
    ch <- 1
    println(<-ch)
}

在playground中运行
打印结果为:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
    /tmp/sandbox117018544/main.go:5 +0x60

死锁了,为什么会这样呢,因为ch是一个无缓冲的channel,在执行到ch <- 1就阻塞了当前goroutine(也就是main函数所在的goroutine),后面打印语句根本没机会执行

稍加修改即能正常运行
在playground中运行

package main

func main() {
    var ch = make(chan int)
    go func() {
        ch <- 1
        println("sender")
    }()
    println(<-ch)
}

因为此时ch既有发送也有接收而且不在同一个goroutine里面,此时它们不会相互阻塞




分享到:
评论

相关推荐

    基于go语言实现的一个在线聊天demo。主要是为了入门go的goroutine和channel的使用。.zip

    Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: ...

    Golang中channel使用的一些小技巧

    在Golang中,channel是一个强大的特性,它允许goroutines之间的同步和通信。本文将深入探讨一些使用channel的小技巧,帮助你...通过熟练掌握这些技巧,你可以更好地利用Go语言的并发特性,编写出高效且易于维护的程序。

    go语言电子书.zip

    Go语言支持C风格的语法,同时引入了诸如goroutine(轻量级线程)和channel(通信机制)等特性,使得并发编程变得简单而高效。Go语言的垃圾回收机制则减轻了程序员管理内存的负担,增加了代码的安全性。 在《Go语言...

    Go语言协程goroutine和管道channel教程.PDF

    ### Go语言协程goroutine与管道channel教程 #### 一、引言 Go语言作为一种现代编程语言,以其简洁高效的语法和强大的并发模型受到广大开发者的喜爱。其中,协程(goroutine)和管道(channel)是Go语言实现高效并发...

    golang基础教程-go语言快速入门.zip

    2. **并发支持**:Go语言内置goroutine和channel,使得并发编程变得极其简单。 3. **垃圾回收**:Go语言有自动的内存管理机制,无需程序员手动进行内存分配和释放。 4. **静态链接**:Go编译出的可执行文件包含所有...

    Go语言实战.pdf_go语言_Go_go_Go语言实战_

    Go语言,又称Golang,是由Google开发的一种静态类型的、编译型的、并发型的、垃圾回收的编程语言。自2009年发布以来,Go语言因其简洁、高效的语法和强大的并发处理能力,逐渐在云计算、微服务、容器等领域获得了广泛...

    GO 语言学习辅导共220页.pdf

    然后,通过创建一个简单的Go语言应用程序——FIBONACCI数列,来展示LITEIDE的使用方法。这个示例项目包括了项目结构的建立,以及编写和运行计算斐波那契数列的代码,帮助读者实际操作,更好地理解和掌握Go语言的基本...

    go语言channel实现多核并行化运行的方法

    Go语言,也被称为Golang,是由Google开发的一种静态类型的、编译型的、并发型的、垃圾回收的、强类型的语言。它以其内置的并发原语而著名,这些原语使得编写能够充分利用多核处理器的程序变得简单。在Go语言中,`...

    基于go语言简单的用户管理系统.zip

    Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: ...

    Go-一个使用golang开发的开源wiki系统。

    1. **并发处理**: Go语言的goroutine和channel机制使得编写并发程序变得简单。goroutine是轻量级线程,可以高效地运行大量并发任务,而channel则提供了安全的数据通信方式,避免了多线程环境下的数据竞争问题。 2. ...

    Go语言实战_golang教程_Go_go_

    2. **并发模型**:Go语言内置了goroutine和channel,它们提供了一种轻量级的线程实现,使得编写高并发程序变得简单。goroutine是协程,其开销小,可以大量并发运行,而channel则用于goroutine之间的通信,实现数据...

    Go语言技术参考手册 中文PDF版

    - **简洁性**:Go语言语法简单明了,易于学习。 - **高效性**:Go语言编译速度快,执行效率高。 - **并发支持**:Go通过goroutine和channel机制提供内置的并发支持,简化了并发编程的复杂度。 - **环境影响因素*...

    golang开发中channel使用

    channel[通道]是golang的一种重要特性,正是因为channel的存在才使得golang不同于其它语言。channel使得并发编程变得简单容易有趣。 channel的概念和语法 一个channel可以理解为一个先进先出的消息队列。channel用来...

    Go语言学习笔记.pdf

    Go语言是一种开源编程语言,具有简单易学、高性能、跨平台等特性,目前已经成为构建高效、可靠的应用程序的重要选择。Go语言在计算机编程领域的重要性不断提升,特别是在云平台、分布式系统和并发处理等领域。为了...

    Go语言中 Channel 详解

    Go 语言中的 channel 是实现 goroutine 间无锁通信的关键机制,他使得写多线程并发程序变得简单、灵活、触手可得。下面就个人理解对 channel 使用过程中应该注意的地方进行一个简要的总结。

    Go语言15套教程(百度网盘)

    - **并发模型**:深入理解Go语言的并发模型,包括goroutine和channel的使用技巧。 - **内存管理**:探讨Go语言中的垃圾回收机制及其对性能的影响。 - **错误处理**:介绍Go语言特有的错误处理方式,如使用error类型...

    go语言高级编程_cut6zj_go语言_Go_golang_golang高级编程_

    理解如何正确地使用goroutine和channel是提升Go语言编程能力的关键。 2. **接口(Interface)**:Go语言的接口设计十分灵活,它是一种动态类型检查机制。通过接口,我们可以实现多态性,编写出更加通用和可复用的...

    20小时入门学会go语言.docx

    1. 并发原生支持:Go语言通过goroutine和channel实现了轻量级线程,使得并发编程变得简单高效。 2. 垃圾回收(GC):Go语言内建了垃圾回收机制,自动管理内存,减轻了程序员的工作负担。 3. 动态和静态的结合:虽然...

Global site tag (gtag.js) - Google Analytics