天天看点

周威学Go从入门到放弃第十篇(多线程)

go语言多线程开发特别容易入门,通过go关键字实现,代码如下:

package main

import (
	"fmt"
	"runtime"
)

func say(s string) {
	for i := 0; i < 5; i++ {
		runtime.Gosched()
		fmt.Println(s)
	}
}

func main() {
	go say("world") //开一个新的Goroutines执行
	say("hello")    //当前Goroutines执行
}




/usr/local/go/bin/go build [/Users/zhouwei/go]
成功: 进程退出代码 0.
/Users/zhouwei/go/go  [/Users/zhouwei/go]
hello
hello
hello
hello
hello
成功: 进程退出代码 0.
           

 从执行结果看,好像并没有执行      go say("world") 的内容,也没有报错,原因是什么?

估计是因为main主程速度太快,来不及执行就已经结束了,尝试一下

package main

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

func say(s string) {
	for i := 0; i < 5; i++ {
		runtime.Gosched()
		fmt.Println(s)
	}
}

func main() {
	go say("world") //开一个新的Goroutines执行
	say("hello")    //当前Goroutines执行
	time.Sleep(time.Second)
}


/usr/local/go/bin/go build [/Users/zhouwei/go]
成功: 进程退出代码 0.
/Users/zhouwei/go/go  [/Users/zhouwei/go]
hello
hello
hello
hello
world
hello
world
world
world
world
成功: 进程退出代码 0.
           

从打印结果看,果然加了一个休眠一秒,有结果了。具体是不是因为这个原因.

抄的解释:原文地址:https://blog.csdn.net/u011304970/article/details/75096323?locationnum=4&fps=1

  • 当创建一个Go协程时,创建这个Go协程的语句立即返回。与函数不同,程序流程不会等待Go协程结束再继续执行。程序流程在开启Go协程后立即返回并开始执行下一行代码,忽略Go协程的任何返回值。
  • 在主协程存在时才能运行其他协程,主协程终止则程序终止,其他协程也将终止。

 线程通信

go线程之间的通信通过channel(看起来内部实现是个队列)来实现的,看示例:

package main

import (
	. "fmt"
)
//从打印结果看,猜测实现是一个队列,先入先出
var ch chan int = make(chan int)

func main() {

	go add(1, 2)
	Println(<-ch) //打印channel中的内容
	Println(<-ch) //打印channel中的内容

}

func add(a int, b int) int {
	ch <- a + b //把计算的结果存到channel中
	ch <- 1     //把计算的结果存到channel中
	return a + b
}


/usr/local/go/bin/go build [/Users/zhouwei/go]
成功: 进程退出代码 0.
/Users/zhouwei/go/go  [/Users/zhouwei/go]
3
1
成功: 进程退出代码 0.
           

结合示例1,2代码来看,channel是阻塞队列机制,出channel中取数据,存数据都会阻塞,这也是为什么能正常跑下去的原因(没有因为1中所说太快直接不执行了)