go语言学习I青训营

54 阅读3分钟

Goroutine&channel

Goroutine基本介绍 进程和线程说明

进程就是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位#线程是进程的一个执行实例,是程序执行的最小单元,它是比进程更小的能独立运行的基本单位

#一个进程可以创建和销毁多个线程,同一个进程中的多个线程可以并发执行 #一个程序至少有一个进程,一个进程至少有一个线程 并发和并行 并发:多线程程序在单核上运行 并行:多线程程序在多核上运行 Go协程和go主线程

go主线程:一个go线程上,可以起多个协程# go协程的特点: *有独立的栈空间 *共享程序堆空间 *调度由用户控制 *协程是轻量级的线程代码实例:import(

"fmt"
"strconv"
"time" ) functest() {
fori :=0;i <10;i++ { fmt.Println("hello world~"+strconv.Itoa(i)) time.Sleep(time.Second)
} } funcmain() {
gotest()
fori :=0;i <10;i++ {
fmt.Println("hello goland~"+strconv.Itoa(i)) time.Sleep(time.Second) } } 说明: #如果主线程退出了,则协程即使没有执行完毕也会退出#协程也可以在主线程没有退出前就自动结束 小结: #主线程是一个物理线程,直接作用在cpu上,是重量级的,非常耗费cpu资源#协程从主线程开始的,是轻量级的线程,是逻辑态,对资源消耗相对小

golang的协程机制是重要特点,可以轻松开启上万个协程,其他编程语言的并发机制是一般基于线程的,开启过多的线程,资源耗费大(MPG模式基本介绍M:操作系统的主线程P:协程执行需要的上下文G:协程)

管道介绍

channel本质就是一个数据结构——队列#数据是先进先出#线程安全,多goroutine访问时,不需要加锁,就是说channel本身就是线程安全的

channel有类型的,一个string的channel只能存放string数据类型定义声明Var变量名chan数据类型举例:Var intChan chan int

Var mapChan chan map[int]string Var perChan chan Person…… 说明:

channel是引用类型

channel必须初始化才能写入数据,即make后才能使用#管道是有类型的,intChan只能写入整数int

注意事项:

channel中只能存放指定数据类型

channel的数据放满后,就不能再放入了#如果从channel取出数据后,可以继续放入

#在没有使用协程的情况下,如果channel数据被取完了,再取就会报dead lock channel的关闭 使用内置函数close()可以关闭channel,当channel关闭后,就不能再向channel写数据了,但是仍然可以从该channel中读取数据。 Channel的遍历 channel支持for_range的方式进行遍历,请注意以下两个细节: #在遍历时,如果channel没有关闭,则会出现deadlock的错误 #在遍历时,如果channel已经关闭,则会正常遍历数据,遍历完后,就会退出遍历 注意事项:

channel可以声明为只读或者只写 #使用select可以解决从管道读取数据的阻塞问题

goroutine中使用recover,解决协程中出现panic,导致程序崩��问题说明:如果我们起了一个协程,但是这个协程出现了panic,如果我们没有捕获这个panic,就会造成整个程序崩溃,这时我们可以在goroutine中使用recover来捕获panic进行处理,这样即时这个协程发生的问题,但是线程仍然不受影响,可以继续执行

心得体会:go管道并发简单易用高效易于扩展,竞争少,可以使代码更简洁,提高代码可重用性。go语言的管道并发相比于传统的多线程编程更加简单高效和安全,在编写并发程序时是一个不错的选择。