【Go自学版】02-goroutine

【Go自学版】02-goroutine_第1张图片
利用时间片分割进程,致使宏观上A,B,C同时执行(并发)

【Go自学版】02-goroutine_第2张图片
CPU利用率包含了执行和切换,进程/线程的数量越多,切换成本也会增大

【Go自学版】02-goroutine_第3张图片

【Go自学版】02-goroutine_第4张图片

【Go自学版】02-goroutine_第5张图片

【Go自学版】02-goroutine_第6张图片
最大并行数:GOMAXPROCS

work stealing: 偷其他队列的G
hand off: 当前G1阻塞,创建/唤醒一个thread,移动当前本地队列至其上

func newTask() {
	i := 0
	for {
		i++
		fmt.Printf("new Goroutine: i = %d\n", i)
		time.Sleep(1 * time.Second)
	}
}

func main() {
	/*
	go newTask()
	i := 0
	for {
		i++
		fmt.Printf("main Goroutine: i = %d\n", i)
		time.Sleep(1 * time.Second)
	}
	*/
	go func() {
		defer fmt.Println("A.defer")

		func() {
			defer fmt.Println("B.defer")
			
			runtime.Goexit() // 退出Goroutine
			
			fmt.Println("B")
		}()

		fmt.Println("A")
	}()
	for {
		time.Sleep(1 * time.Second)
	}
}

【Go自学版】02-goroutine_第7张图片

// channel
func main() {
	// 无缓存
	c := make(chan int)

	go func() {
		defer fmt.Println("goroutine end")
		fmt.Println("goroutine running")
		c <- 114514 // 114514 发送到 c
	}()

	num := <-c // c 中接收数据并赋值给num
	fmt.Printf("num = %d\n", num)
	fmt.Println("main goroutine end")
}

【Go自学版】02-goroutine_第8张图片

func main() {
	// 有缓存
	c := make(chan int, 3)
	fmt.Println("len(c) = ", len(c), ", cap(c) = ", cap(c))

	go func() {
		defer fmt.Println("子go结束")
		for i := 0; i < 3; i++ {
			c <- i
			fmt.Println("子go正在运行:len(c) = ", len(c), "cap(c) = ", cap(c))
			fmt.Println("发送元素 = ", i)
		}
	}()

	time.Sleep(2 * time.Second)

	for i := 0; i < 3; i++ {
		num := <-c
		fmt.Println("num = ", num)
	}

	fmt.Println("main 结束")

}
func main() {
	// channel 需要初始化
	c := make(chan int)

	go func() {
		for i := 0; i < 5; i++ {
			c <- i
		}
		// 关闭 channel 的发送端
		close(c)
	}()
	
	// 写法一
	// 接收 channel 数据之前先判断 channel 状态
	for {
		data, ok := <-c
		if ok {
			println("data: ", data)
		} else {
			break
		}
	}
	
	// 写法二
	// 无数据自动阻塞
	for data := range c {
		fmt.Println("data:", data)
	}

	
	fmt.Println("Main Finished")
}
// select 语句 控制多个 channel
func fib(c, quit chan int) {
	x, y := 1, 1

	for {
		select {
		case c <- x:
			x, y = y, x+y
		case <-quit:
			fmt.Println("quit")
			return
		}
	}
}

func main() {
	c := make(chan int)
	quit := make(chan int)

	go func() {
		for i := 0; i < 6; i++ {
			fmt.Println(<-c)
		}
		quit <- 0
	}()

	fib(c, quit)
}

reference

B站刘丹冰Aceld

你可能感兴趣的:(golang)