Go并发 协程

协程和线程的区别,协程特点如下:

  1. 该任务的业务代码主动要求切换,即主动让出所有权
  2. 发生了IO,导致执行阻塞。

##线程:
两个线程互相交替完成。
这里写图片描述
这里写图片描述

但是线程间切换的系统开销很大,需要保存上下文。

协程

CPU没有权利停止协程A,去执行协程B
只有以下两种情况

  1. 该任务的业务代码主动要求切换,即主动让出所有权
  2. 发生了IO,导致执行阻塞。(例如,协程A读文件或读channel阻塞,CPU会切换至协程B)

协程正常运行,CPU无法主动切换协程

这里写图片描述
这里写图片描述

package main

import (
	"fmt"
	"time"
	"strconv"
)

func main(){
	// 协程1
	go func(){
		for i := 0; i < 100; i++ {
			fmt.Println("goroutine1: " + strconv.Itoa(i))
		}
	}()

	// 协程2
	go func(){
		for i := 100; i < 200; i++{
			fmt.Println("goroutine2: " + strconv.Itoa(i))
		}
	}()

	time.Sleep(time.Second)
}

协程A主动出让所有权

等其他协程跑完时,再跑A协程剩下的。
这里写图片描述

package main

import (
	"fmt"
	"time"
	"strconv"
	"runtime"
)

func main(){
	// 协程1
	go func(){
		for i := 0; i < 100; i++ {
			if i == 10 {
				runtime.Gosched()
			}
			fmt.Println("goroutine1: " + strconv.Itoa(i))
		}
	}()

	// 协程2
	go func(){
		for i := 100; i < 200; i++{
			fmt.Println("goroutine2: " + strconv.Itoa(i))
		}
	}()

	time.Sleep(time.Second)
}

GOROOT=/usr/local/Cellar/go/1.9.2/libexec #gosetup
GOPATH=/Users/sunyuchuan/codes/my-go-codes:/Users/sunyuchuan/go #gosetup
/usr/local/Cellar/go/1.9.2/libexec/bin/go build -i -o /private/var/folders/s0/0gwfh5px0g1708zytjxl2b680000gn/T/___go_build_main_go /Users/sunyuchuan/codes/my-go-codes/bfchannel/main.go #gosetup
/private/var/folders/s0/0gwfh5px0g1708zytjxl2b680000gn/T/___go_build_main_go #gosetup
goroutine2: 100
goroutine2: 101
goroutine2: 102
goroutine2: 103
goroutine2: 104
goroutine2: 105
goroutine2: 106
goroutine2: 107
goroutine2: 108
goroutine2: 109
goroutine2: 110
goroutine2: 111
goroutine2: 112
goroutine2: 113
goroutine2: 114
goroutine2: 115
goroutine2: 116
goroutine2: 117
goroutine2: 118
goroutine2: 119
goroutine2: 120
goroutine1: 0
goroutine1: 1
goroutine1: 2
goroutine1: 3
goroutine1: 4
goroutine1: 5
goroutine1: 6
goroutine1: 7
goroutine1: 8
goroutine1: 9
goroutine2: 121
goroutine2: 122
goroutine2: 123
goroutine1: 10
goroutine1: 11
goroutine1: 12
goroutine1: 13
goroutine1: 14
goroutine1: 15
goroutine1: 16
goroutine1: 17
goroutine1: 18
goroutine1: 19
goroutine1: 20
goroutine1: 21
goroutine1: 22
goroutine1: 23
goroutine1: 24
goroutine1: 25
goroutine1: 26
goroutine1: 27
goroutine1: 28
goroutine1: 29
goroutine1: 30
goroutine1: 31
goroutine1: 32
goroutine1: 33
goroutine1: 34
goroutine1: 35
goroutine1: 36
goroutine1: 37
goroutine1: 38
goroutine1: 39
goroutine1: 40
goroutine1: 41
goroutine2: 124
goroutine2: 125
goroutine2: 126
goroutine2: 127
goroutine2: 128
goroutine2: 129
goroutine2: 130
goroutine2: 131
goroutine2: 132
goroutine1: 42
goroutine1: 43
goroutine1: 44
goroutine1: 45
goroutine1: 46
goroutine1: 47
goroutine1: 48
goroutine1: 49
goroutine1: 50
goroutine1: 51
goroutine1: 52
goroutine1: 53
goroutine1: 54
goroutine1: 55
goroutine1: 56
goroutine1: 57
goroutine1: 58
goroutine1: 59
goroutine1: 60
goroutine1: 61
goroutine1: 62
goroutine1: 63
goroutine1: 64
goroutine1: 65
goroutine1: 66
goroutine1: 67
goroutine1: 68
goroutine1: 69
goroutine1: 70
goroutine1: 71
goroutine1: 72
goroutine1: 73
goroutine1: 74
goroutine1: 75
goroutine1: 76
goroutine1: 77
goroutine1: 78
goroutine2: 133
goroutine2: 134
goroutine2: 135
goroutine2: 136
goroutine2: 137
goroutine2: 138
goroutine2: 139
goroutine2: 140
goroutine2: 141
goroutine2: 142
goroutine2: 143
goroutine2: 144
goroutine2: 145
goroutine2: 146
goroutine2: 147
goroutine2: 148
goroutine2: 149
goroutine2: 150
goroutine2: 151
goroutine2: 152
goroutine2: 153
goroutine2: 154
goroutine2: 155
goroutine2: 156
goroutine2: 157
goroutine2: 158
goroutine2: 159
goroutine2: 160
goroutine2: 161
goroutine1: 79
goroutine1: 80
goroutine1: 81
goroutine1: 82
goroutine1: 83
goroutine1: 84
goroutine1: 85
goroutine1: 86
goroutine1: 87
goroutine1: 88
goroutine1: 89
goroutine1: 90
goroutine1: 91
goroutine1: 92
goroutine1: 93
goroutine1: 94
goroutine1: 95
goroutine1: 96
goroutine1: 97
goroutine1: 98
goroutine1: 99
goroutine2: 162
goroutine2: 163
goroutine2: 164
goroutine2: 165
goroutine2: 166
goroutine2: 167
goroutine2: 168
goroutine2: 169
goroutine2: 170
goroutine2: 171
goroutine2: 172
goroutine2: 173
goroutine2: 174
goroutine2: 175
goroutine2: 176
goroutine2: 177
goroutine2: 178
goroutine2: 179
goroutine2: 180
goroutine2: 181
goroutine2: 182
goroutine2: 183
goroutine2: 184
goroutine2: 185
goroutine2: 186
goroutine2: 187
goroutine2: 188
goroutine2: 189
goroutine2: 190
goroutine2: 191
goroutine2: 192
goroutine2: 193
goroutine2: 194
goroutine2: 195
goroutine2: 196
goroutine2: 197
goroutine2: 198
goroutine2: 199

Process finished with exit code 0
运行效果不对

协程A阻塞,协程B先运行,等阻塞恢复后,协程A再继续

这里写图片描述

package main

import (
	"fmt"
	"time"
	"strconv"
//	"runtime"
)

var ch chan int

func main(){
	// 协程1
	go func(){
		for i := 0; i < 100; i++ {
			if i == 10 {
				// runtime.Gosched()
				<-ch		// 读无值的chan
			}
			fmt.Println("goroutine1: " + strconv.Itoa(i))
		}
	}()

	// 协程2
	go func(){
		for i := 100; i < 200; i++{
			fmt.Println("goroutine2: " + strconv.Itoa(i))
		}
		ch <- 1				// 协程2结束,开始协程1
	}()

	time.Sleep(time.Second)
}

运行效果也不对
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值