Go语言中Go协程的阻塞行为

huangapple go评论121阅读模式
英文:

Blocking Behaviour of GoRoutines in Golang

问题

给定以下伪代码:

func main() {
  go runFuncOne()
}

func runFuncOne() bool {
  runFuncTwo() 
  return true
}

func runFuncTwo() bool {
  // Do some heavy work
  return true
}

runFuncTwo只会对runFuncOne(调用它的goroutine)进行阻塞,还是会对main()进行阻塞,因为它本身并没有作为goroutine运行?

我的假设是main()将打开一个线程,在该线程中runFuncOne()runFuncTwo()将运行。runFuncTwo()中执行的任何工作将只会阻塞runFuncOne()的这个实例。

英文:

Given the following pseudo-code:

func main() {
  go runFuncOne()
}

func runFuncOne() bool {
  runFuncTwo() 
  return true
}

func runFuncTwo() bool {
  // Do some heavy work
  return true
}

Would runFuncTwo only be blocking to runFuncOne (the calling goroutine) or would runFuncTwo also block main() as it is not itself running as a goroutine?

My assumption is that main() will open a thread within which runFuncOne() and runFuncTwo() will then operate. Any work performed within runFuncTwo() will then only block this instance of runFuncOne()?

答案1

得分: 4

runFuncTwo只会运行两个代码块中的runFuncOne,因为它们都在单独的Go协程中运行。

但请注意,main()函数会继续执行并退出,导致程序退出。为了避免这种情况并让runFuncTwo完成,你应该使用sync.WaitGroup。

英文:

runFuncTwo blocks runFuncOne only, as both are running in a separate Go routine.

Note though that main() will therefore continue and exit, causing the program to exit. To avoid this and all runFuncTwo to complete, you should use a sync.WaitGroup.

答案2

得分: 1

《Go编程语言规范》

Go语言中的goroutine

在调用的goroutine中,函数值和参数会像平常一样进行评估,但与常规调用不同的是,程序执行不会等待被调用的函数完成。相反,该函数会在一个新的goroutine中独立开始执行。当函数终止时,它的goroutine也会终止。如果函数有返回值,在函数完成时它们会被丢弃。

func main() {
  go runFuncOne()
}

main函数会将runFuncOne()作为一个goroutine调用,然后立即退出程序,不等待runFuncOne()完成。

func runFuncOne() bool {
  runFuncTwo() 
  return true
}

func runFuncTwo() bool {
  // 做一些耗时的工作
  return true
}

runFuncOne()函数调用runFuncTwo(),因此它会等待runFuncTwo()完成。

英文:

> The Go Programming Language Specification
>
> Go statements
>
> The function value and parameters are evaluated as usual in the
> calling goroutine, but unlike with a regular call, program execution
> does not wait for the invoked function to complete. Instead, the
> function begins executing independently in a new goroutine. When the
> function terminates, its goroutine also terminates. If the function
> has any return values, they are discarded when the function completes.

func main() {
  go runFuncOne()
}

main will invoke runFuncOne() as a goroutine and then exit the program immediately, terminating runFuncOne() without waiting for it to complete.

func runFuncOne() bool {
  runFuncTwo() 
  return true
}

func runFuncTwo() bool {
  // Do some heavy work
  return true
}

runFuncOne() makes a function call to runFuncTwo() so it will wait for runFuncTwo() to complete.

答案3

得分: 1

也可以使用通道进行同步:

package main

import (
	"fmt"
	"time"
)

func main() {
	var ch chan int = make(chan int)
	go runFuncOne(ch)
	fmt.Println("Waiting..")
	fmt.Println(<-ch)
}

func runFuncOne(ch chan int) {
	runFuncTwo(ch)
	ch <- 1
}

func runFuncTwo(ch chan int) bool {
	time.Sleep(1 * time.Second)
	fmt.Println("Done working..")
	return true
}

runFuncOne 的返回类型不重要,如果你在调用它时使用了一个 goroutine。

英文:

Can also use a channel for synchronization:

package main

import (
	&quot;fmt&quot;
	&quot;time&quot;
)

func main() {
	var ch chan int = make(chan int)
	go runFuncOne(ch)
	fmt.Println(&quot;Waiting..&quot;)
	fmt.Println(&lt;-ch)
}

func runFuncOne(ch chan int) {
	runFuncTwo(ch)
	ch &lt;- 1
}

func runFuncTwo(ch chan int) bool {
	time.Sleep(1 * time.Second)
	fmt.Println(&quot;Done working..&quot;)
	return true
}

https://play.golang.org/p/h1S4TSdT0w

Return type of runFuncOne won't be of consequence if you are calling it with a go routine.

huangapple
  • 本文由 发表于 2017年9月3日 12:06:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/46020175.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定