GO 的goroutine(协程)和thread(线程)有什么区别

Thread 线程

在传统的web编程中,经常要用到多线程。比如 java,来一个websocket 即开启一个thread(线程)。

而thread的数目是有限的,一般的电脑可以同时开的thread数量大概几千个。而GO语言可以开启的goroutine,却可以达到几百万个,因此很显然goroutine不等于thread。

那么Thread和Goroutine的区别是什么?

Thread,即多个程序切换执行
示例代码:

线程1
thread1(){
for i = 1:10
print("Thread1 : ",i)
}
线程2
thread1(){
for i = 1:10
print("Thread2 : ",i)
}

执行结果是:

thread1 : 1
thread2 : 1
thread1 : 2
thread2 : 2
thread1 : 3
thread2 : 3
thread1 : 4
thread2 : 4
thread1 : 5
thread2 : 5

可以看到两个thread交替执行,最后产生同时执行的效果

Goroutine 协程

而协程则完全不是这么一回事,协程是不切换的,执行完协程A,再执行协程B
协程切换的条件有两个

  1. 该协程主动要求切换给其他协程
  2. 该协程执行时遇到堵塞,比如在等待 IO 读数据,或者读channel时陷入等待,这样就会被CPU强行切换到其他协程

代码测试

package main

import (
	"fmt"
	"time"
)

func routineA() {
	for i := 1; i <= 5; i++ {
		fmt.Printf("Goroutine A : %d\n", i)
	}
}
func routineB() {
	for i := 1; i <= 5; i++ {
		fmt.Printf("Goroutine B : %d\n", i)
	}
}
func main() {
	go routineA()
	go routineB()
	time.Sleep(time.Second * 2)
}

测试结果
GO 的goroutine(协程)和thread(线程)有什么区别_第1张图片

很显然,goroutine A执行完,然后才执行 goroutine B

测试第一个特性

该协程主动要求切换给其他协程
使用的代码 runtime.Gosched()

package main

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

func routineA() {
	for i := 1; i <= 5; i++ {
		fmt.Printf("Goroutine A : %d\n", i)
		if 3 == i {
			runtime.Gosched()
		}
	}
}
func routineB() {
	for i := 1; i <= 5; i++ {
		fmt.Printf("Goroutine B : %d\n", i)
	}
}
func main() {
	go routineA()
	go routineB()
	time.Sleep(time.Second * 2)
}

结果
GO 的goroutine(协程)和thread(线程)有什么区别_第2张图片

测试第二个特性

该协程执行时遇到堵塞,比如在等待 IO 读数据,或者读channel时陷入等待,这样就会被CPU强行切换到其他协程

使用channel的读写作为测试,代码如下

package main

import (
	"fmt"
	"time"
)

var ch chan int

func routineA() {
	for i := 1; i <= 5; i++ {
		fmt.Printf("Goroutine A : %d\n", i)
		if 3 == i {
			a := <-ch
			fmt.Printf("Goroutine A : read channal value %d\n", a)
		}
	}
}
func routineB() {
	for i := 1; i <= 5; i++ {
		fmt.Printf("Goroutine B : %d\n", i)
		if 4 == i {
			ch <- 3
			fmt.Printf("Goroutine B : write channal value\n")
		}
	}
}
func main() {
	ch = make(chan int)
	go routineA()
	go routineB()
	time.Sleep(time.Second * 2)
}

执行结果
GO 的goroutine(协程)和thread(线程)有什么区别_第3张图片

你可能感兴趣的:(GO 的goroutine(协程)和thread(线程)有什么区别)