4-golang协程(goroutine)和管道(channel)

2024-08-28 02:32

本文主要是介绍4-golang协程(goroutine)和管道(channel),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

4-golang协程(goroutine)和管道(channel)

1. 并发和并行

多线程程序在单核上运行,就是并发

多线程程序在多核上运行,就是并行

2. go协程和线程

  • Go主线程(也可以称为线程,可以理解为进程):一个Go线程上可以起多个协程,协程是轻量级的线程
  • Go协程的特点
    • 有独立的栈空间
    • 共享程序堆空间
    • 调度由用户控制
    • 协程是轻量级的线程
func test() {for i := 0; i < 10; i++ {fmt.Println("test() hello world " + strconv.Itoa(i))time.Sleep(time.Second)}
}func main() {go test() // 开启了一个协程for i := 0; i < 10; i++ {fmt.Println("main() hello golang " + strconv.Itoa(i))time.Sleep(time.Second)}
}
  • 如果主线程退出了,则协程及时还没有执行完毕,也会退出
  • 写成也可以在主线程没有退出前就自己结束了,比如完成了自己的任务

3. goroutine的调度模型–MPG模式

M:操作系统的主线程(是物理线程)

P:协程执行需要的上下文

G:协程

4. 管道(Channel)

  • channel是一个数据结构,遵循先进先出
  • 多goroutine访问时,不需要加锁,channel是线程安全的
  • 一个channel中的数据,数据类型要一致。(一个string的channel,只能存放string数据类型)
  • channel需要make后使用,make时需要设置channel长度
  • channel数据放满后,再放数据会报错,取出数据后,可以再放数据
  • 在没有协程的情况下,channel数据取完后,再取数据会报错
  • 使用内置的 close(channelName) 可以关闭channel,此时不能再向channel写数据,但是可以读数据
  • 遍历channel使用for-range遍历。在遍历时,如果channel没有关闭,则会报错;如果channel已经关闭,会再遍历完成后退出遍历。(遍历不要使用普通for,因为在取出channel数据后,channel长度会改变)
package mainimport "fmt"// write data
func writeData(intChan chan int) {for i := 1; i <= 1000; i++ {// 放入数据intChan <- ifmt.Printf("writeData 写入数据=%v\n", i)}// 写完后关闭close(intChan)
}func readChain(intChan chan int, exitChan chan bool) {for {v, ok := <-intChanif !ok {break}fmt.Printf("readData 读到数据=%v\n", v)}// 读完数据后,任务完成exitChan <- trueclose(exitChan)
}func main() {// 创建两个管道intChan := make(chan int, 1000)exitChan := make(chan bool, 1)go writeData(intChan)go readChain(intChan, exitChan)for {_, ok := <-exitChanif !ok {break}}}

这篇关于4-golang协程(goroutine)和管道(channel)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1113475

相关文章

C++20管道运算符的实现示例

《C++20管道运算符的实现示例》本文简要介绍C++20管道运算符的使用与实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录标准库的管道运算符使用自己实现类似的管道运算符我们不打算介绍太多,因为它实际属于c++20最为重要的

Golang如何对cron进行二次封装实现指定时间执行定时任务

《Golang如何对cron进行二次封装实现指定时间执行定时任务》:本文主要介绍Golang如何对cron进行二次封装实现指定时间执行定时任务问题,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录背景cron库下载代码示例【1】结构体定义【2】定时任务开启【3】使用示例【4】控制台输出总结背景

Golang如何用gorm实现分页的功能

《Golang如何用gorm实现分页的功能》:本文主要介绍Golang如何用gorm实现分页的功能方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景go库下载初始化数据【1】建表【2】插入数据【3】查看数据4、代码示例【1】gorm结构体定义【2】分页结构体

在Golang中实现定时任务的几种高效方法

《在Golang中实现定时任务的几种高效方法》本文将详细介绍在Golang中实现定时任务的几种高效方法,包括time包中的Ticker和Timer、第三方库cron的使用,以及基于channel和go... 目录背景介绍目的和范围预期读者文档结构概述术语表核心概念与联系故事引入核心概念解释核心概念之间的关系

Golang 日志处理和正则处理的操作方法

《Golang日志处理和正则处理的操作方法》:本文主要介绍Golang日志处理和正则处理的操作方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录1、logx日志处理1.1、logx简介1.2、日志初始化与配置1.3、常用方法1.4、配合defer

Linux基础命令@grep、wc、管道符的使用详解

《Linux基础命令@grep、wc、管道符的使用详解》:本文主要介绍Linux基础命令@grep、wc、管道符的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录grep概念语法作用演示一演示二演示三,带选项 -nwc概念语法作用wc,不带选项-c,统计字节数-

golang float和科学计数法转字符串的实现方式

《golangfloat和科学计数法转字符串的实现方式》:本文主要介绍golangfloat和科学计数法转字符串的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望... 目录golang float和科学计数法转字符串需要对float转字符串做处理总结golang float

golang实现延迟队列(delay queue)的两种实现

《golang实现延迟队列(delayqueue)的两种实现》本文主要介绍了golang实现延迟队列(delayqueue)的两种实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录1 延迟队列:邮件提醒、订单自动取消2 实现2.1 simplChina编程e简单版:go自带的time

Golang实现Redis分布式锁(Lua脚本+可重入+自动续期)

《Golang实现Redis分布式锁(Lua脚本+可重入+自动续期)》本文主要介绍了Golang分布式锁实现,采用Redis+Lua脚本确保原子性,持可重入和自动续期,用于防止超卖及重复下单,具有一定... 目录1 概念应用场景分布式锁必备特性2 思路分析宕机与过期防止误删keyLua保证原子性可重入锁自动

golang 对象池sync.Pool的实现

《golang对象池sync.Pool的实现》:本文主要介绍golang对象池sync.Pool的实现,用于缓存和复用临时对象,以减少内存分配和垃圾回收的压力,下面就来介绍一下,感兴趣的可以了解... 目录sync.Pool的用法原理sync.Pool 的使用示例sync.Pool 的使用场景注意sync.