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

相关文章

Golang HashMap实现原理解析

《GolangHashMap实现原理解析》HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持高效的插入、查找和删除操作,:本文主要介绍GolangH... 目录HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持

Redis Pipeline(管道) 详解

《RedisPipeline(管道)详解》Pipeline管道是Redis提供的一种批量执行命令的机制,通过将多个命令一次性发送到服务器并统一接收响应,减少网络往返次数(RTT),显著提升执行效率... 目录Redis Pipeline 详解1. Pipeline 的核心概念2. 工作原理与性能提升3. 核

golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法

《golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法》:本文主要介绍golang获取当前时间、时间戳和时间字符串及它们之间的相互转换,本文通过实例代码给大家介绍的非常详细,感兴趣... 目录1、获取当前时间2、获取当前时间戳3、获取当前时间的字符串格式4、它们之间的相互转化上篇文章给大家介

golang 日志log与logrus示例详解

《golang日志log与logrus示例详解》log是Go语言标准库中一个简单的日志库,本文给大家介绍golang日志log与logrus示例详解,感兴趣的朋友一起看看吧... 目录一、Go 标准库 log 详解1. 功能特点2. 常用函数3. 示例代码4. 优势和局限二、第三方库 logrus 详解1.

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

Redis中管道操作pipeline的实现

《Redis中管道操作pipeline的实现》RedisPipeline是一种优化客户端与服务器通信的技术,通过批量发送和接收命令减少网络往返次数,提高命令执行效率,本文就来介绍一下Redis中管道操... 目录什么是pipeline场景一:我要向Redis新增大批量的数据分批处理事务( MULTI/EXE

Linux中的进程间通信之匿名管道解读

《Linux中的进程间通信之匿名管道解读》:本文主要介绍Linux中的进程间通信之匿名管道解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、基本概念二、管道1、温故知新2、实现方式3、匿名管道(一)管道中的四种情况(二)管道的特性总结一、基本概念我们知道多

Linux命名管道方式

《Linux命名管道方式》:本文主要介绍Linux命名管道方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、命名管道1、与匿名管道的关系2、工作原理3、系统调用接口4、实现两个进程间通信二、可变参数列表总结一、命名管道1、与匿名管道的关系命名管道由mkf

Golang中拼接字符串的6种方式性能对比

《Golang中拼接字符串的6种方式性能对比》golang的string类型是不可修改的,对于拼接字符串来说,本质上还是创建一个新的对象将数据放进去,主要有6种拼接方式,下面小编就来为大家详细讲讲吧... 目录拼接方式介绍性能对比测试代码测试结果源码分析golang的string类型是不可修改的,对于拼接字

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.