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")
    }
目录
相关文章
|
3月前
|
监控 负载均衡 算法
Golang深入浅出之-Go语言中的协程池设计与实现
【5月更文挑战第3天】本文探讨了Go语言中的协程池设计,用于管理goroutine并优化并发性能。协程池通过限制同时运行的goroutine数量防止资源耗尽,包括任务队列和工作协程两部分。基本实现思路涉及使用channel作为任务队列,固定数量的工作协程处理任务。文章还列举了一个简单的协程池实现示例,并讨论了常见问题如任务队列溢出、协程泄露和任务调度不均,提出了解决方案。通过合理设置缓冲区大小、确保资源释放、优化任务调度以及监控与调试,可以避免这些问题,提升系统性能和稳定性。
99 6
|
11月前
|
并行计算 安全 Go
Golang协程:并发编程的利器
在Go编程语言中,协程(goroutine)是一种轻量级的线程,用于实现并发编程。与传统的线程相比,协程更加高效、简洁,并且易于使用。本篇博客将深入探讨Golang中的协程及其优势。
88 0
|
Linux Go
学习golang(12) 初探:协程(3)多个chan之select选择器
学习golang(12) 初探:协程(3)多个chan之select选择器
203 0
|
缓存 Go
学习golang(11) 初探:协程(2) 协程间通信
学习golang(11) 初探:协程(2) 协程间通信
186 0
|
Shell Go 调度
学习golang(10) 初探:协程(1)
学习golang(10) 初探:协程(1)
132 0
|
Java Go 调度
Golang中的协程(goroutine)
Golang中的协程(goroutine)
82 0
golang 循环创建新协程,发现每次使用的循环变量都一样,都是最后一个
golang 循环创建新协程,发现每次使用的循环变量都一样,都是最后一个
golang 循环创建新协程,发现每次使用的循环变量都一样,都是最后一个
|
Go 调度 Python
大道如青天,协程来通信,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang通道channel的使用EP14
众所周知,Go lang的作用域相对严格,数据之间的通信往往要依靠参数的传递,但如果想在多个协程任务中间做数据通信,就需要通道(channel)的参与,我们可以把数据封装成一个对象,然后把这个对象的指针传入某个通道变量中,另外一个协程从这个通道中读出变量的指针,并处理其指向的内存对象。
大道如青天,协程来通信,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang通道channel的使用EP14
|
Go
Golang协程
Golang协程
104 0
Golang协程
golang 协程并发代码 demo
golang 协程并发代码 demo