• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

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

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

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)
}

测试结果

很显然,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)
}

结果

测试第二个特性

该协程执行时遇到堵塞,比如在等待 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)
}

执行结果


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
go语言简介与环境搭建发布时间:2022-07-10
下一篇:
Linux环境下go安装发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap