Golang 协程

简介: Go语言中,没有线程概念,只有协程goroutine。go语言的并发是由go自己决定,对于开发者是透明的,仅需编码时告知启动几个goroutine即可,其余均不关心和线程相比:- 协程更轻量,一个程序可以启动成千上万个goroutine- 协程是被go runtime 调度执行,线程,由操作系统调度执行。

学习协程前,可以先了解进程,线程的相关内容

goroutine

Go语言中,没有线程概念,只有协程goroutine。

go语言的并发是由go自己决定,对于开发者是透明的,仅需编码时告知启动几个goroutine即可,其余均不关心

和线程相比:

  • 协程更轻量,一个程序可以启动成千上万个goroutine
  • 协程是被go runtime 调度执行,线程,由操作系统调度执行,。

启动协程:使用关键字go 启动

go function()

channel

解决多个协程之间的通信,主要通过使用channel通道

声明channel,使用make函数

// 声明一个channel变量,其数据都是string
ch := make(chan string)

关键字chan,表示channel类型,是一个集合类型,

chan的操作只有两种:

接收:获取chan中的值,操作符为<- chan

发送:向chan发送值,把值放在chan中,操作符为chan<-

channel类似是goroutine的一个管道,一个往管道里发送数据,另一个从管道中取数据,如果在管道中获取不到数据,则将等到取到数据为止

  • 无缓冲channel

    • 声明一个无容量的channel,只起到传输数据的作用
    • 无缓冲channel的发送和接收操作时同时进行,也称为同步channel
  • 有缓冲channel

    • 指定channel容量大小,创建一个有缓冲channel

      ch := make(chan int,5)
    • 有缓冲channel的内部有一个缓冲队列
    • 发送操作向队列尾部插入元素,队列满时则阻塞等待,直到有协程从队列中接收数据从而释放队列空间
    • 接收操作从队列的头部获取元素并把它从队列中删除,队列为空时则阻塞等待,直到有协程向队列中发送数据
    ch := make(chan int,6)
    
    cap(ch) // 获取chan 长度
    close(ch) //关闭chan
  • 单向channel

场景:限制一个channel只接收不发送,或者只发送不接收

select

类似switch,但又有些不同。select只能用于信道channel,所以在这里提及select

select的case后带的是channel的操作,而不是判断条件。

  • select语句只能用于信道channel的读写操作
  • select的case条件是并发执行,会先执行操作成功的那个case先执行,如果多个同时返回时,则随机选择一个执行
  • 如果case条件语句中,存在通道值为nil的读写操作,则该分支会被忽略
  • 对于空select{},会引起死锁
  • 对于for的select{},可能会引起cpu占用过高的问

    ch := make(chan int , 10)
    
    for i := 0; i < size; i++ {
      ch <- 1
    }
    
    select {
      case 1==1:   // 此处运行时会报错
          fmt.Println("equal")
      case v:= <-ch
       fmt.Print(v)
      default:
      fmt.Println("none")
    }
    
    select {
      case 1==1:   // 此处运行时会报错
          fmt.Println("equal")
      case v:= <-ch
       fmt.Print(v)
      case b:= <-ch
       fmt.Print(b)
      default:
      fmt.Println("none")
    }
目录
相关文章
|
2月前
|
安全 Go
Golang语言goroutine协程并发安全及锁机制
这篇文章是关于Go语言中多协程操作同一数据问题、互斥锁Mutex和读写互斥锁RWMutex的详细介绍及使用案例,涵盖了如何使用这些同步原语来解决并发访问共享资源时的数据安全问题。
86 4
|
14天前
|
存储 安全 测试技术
GoLang协程Goroutiney原理与GMP模型详解
本文详细介绍了Go语言中的Goroutine及其背后的GMP模型。Goroutine是Go语言中的一种轻量级线程,由Go运行时管理,支持高效的并发编程。文章讲解了Goroutine的创建、调度、上下文切换和栈管理等核心机制,并通过示例代码展示了如何使用Goroutine。GMP模型(Goroutine、Processor、Machine)是Go运行时调度Goroutine的基础,通过合理的调度策略,实现了高并发和高性能的程序执行。
76 29
|
12天前
|
Go 计算机视觉
在Golang高并发环境中如何进行协程同步?
在此示例中,使用互斥锁来保护对共享计数器变量 c 的访问,确保并发的 HTTP 请求不会产生数据竞争。
32 3
|
12天前
|
负载均衡 算法 Go
GoLang协程Goroutiney原理与GMP模型详解
【11月更文挑战第4天】Goroutine 是 Go 语言中的轻量级线程,由 Go 运行时管理,创建和销毁开销小,适合高并发场景。其调度采用非抢占式和协作式多任务处理结合的方式。GMP 模型包括 G(Goroutine)、M(系统线程)和 P(逻辑处理器),通过工作窃取算法实现负载均衡,确保高效利用系统资源。
|
2月前
|
Go 调度
Golang语言goroutine协程篇
这篇文章是关于Go语言goroutine协程的详细教程,涵盖了并发编程的常见术语、goroutine的创建和调度、使用sync.WaitGroup控制协程退出以及如何通过GOMAXPROCS设置程序并发时占用的CPU逻辑核心数。
50 4
Golang语言goroutine协程篇
|
3月前
|
NoSQL Unix 编译器
Golang协程goroutine的调度与状态变迁分析
文章深入分析了Golang中goroutine的调度和状态变迁,包括Grunnable、Gwaiting、Grunning和Gsyscall等状态,以及它们之间的转换条件和原理,帮助理解Go调度器的内部机制。
46 0
|
6月前
|
监控 负载均衡 算法
Golang深入浅出之-Go语言中的协程池设计与实现
【5月更文挑战第3天】本文探讨了Go语言中的协程池设计,用于管理goroutine并优化并发性能。协程池通过限制同时运行的goroutine数量防止资源耗尽,包括任务队列和工作协程两部分。基本实现思路涉及使用channel作为任务队列,固定数量的工作协程处理任务。文章还列举了一个简单的协程池实现示例,并讨论了常见问题如任务队列溢出、协程泄露和任务调度不均,提出了解决方案。通过合理设置缓冲区大小、确保资源释放、优化任务调度以及监控与调试,可以避免这些问题,提升系统性能和稳定性。
205 6
|
并行计算 安全 Go
Golang协程:并发编程的利器
在Go编程语言中,协程(goroutine)是一种轻量级的线程,用于实现并发编程。与传统的线程相比,协程更加高效、简洁,并且易于使用。本篇博客将深入探讨Golang中的协程及其优势。
119 0
|
Linux Go
学习golang(12) 初探:协程(3)多个chan之select选择器
学习golang(12) 初探:协程(3)多个chan之select选择器
233 0
|
缓存 Go
学习golang(11) 初探:协程(2) 协程间通信
学习golang(11) 初探:协程(2) 协程间通信
199 0