匿名函数在Go协程中似乎没有执行。

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

Anonymous function doesn't seem to execute in Go routine

问题

我有以下代码,请特别注意匿名函数部分:

func saveMatterNodes(matterId int, nodes []doculaw.LitigationNode) (bool, error) {

	var (
		err  error
		resp *http.Response
	)

	// 在多个线程中执行此操作
	for _, node := range nodes {
		fmt.Println("in loops")
		go func() {
			postValues := doculaw.LitigationNode{
				Name:        node.Name,
				Description: node.Description,
				Days:        node.Days,
				Date:        node.Date,
				IsFinalStep: false,
				Completed:   false,
				Matter:      matterId}

			b := new(bytes.Buffer)
			json.NewEncoder(b).Encode(postValues)
			resp, err = http.Post("http://127.0.0.1:8001/matterNode/", "application/json", b)
			io.Copy(os.Stdout, resp.Body)

			fmt.Println("Respone from http post", resp)
			if err != nil {
				fmt.Println(err)
			}
		}()

	}

	if err != nil {
		return false, err
	} else {
		return true, nil
	}

}

如果我删除 go func() {}() 部分,只保留其中的代码,似乎可以正常执行,但是一旦我添加回去,它就不执行了。有任何想法为什么会这样吗?我最初认为可能是因为它在不同的线程上执行,但是根据我的 Web 服务访问日志,似乎并非如此。

英文:

I have the following code. Pay special attention to the anonymous function:

func saveMatterNodes(matterId int, nodes []doculaw.LitigationNode) (bool, error) {

	var (
		err  error
		resp *http.Response
	)

	// Do this in multiple threads
	for _, node := range nodes {
		fmt.Println("in loops")
		go func() {
			postValues := doculaw.LitigationNode{
				Name:        node.Name,
				Description: node.Description,
				Days:        node.Days,
				Date:        node.Date,
				IsFinalStep: false,
				Completed:   false,
				Matter:      matterId}

			b := new(bytes.Buffer)
			json.NewEncoder(b).Encode(postValues)
			resp, err = http.Post("http://127.0.0.1:8001/matterNode/", "application/json", b)
			io.Copy(os.Stdout, resp.Body)

			fmt.Println("Respone from http post", resp)
			if err != nil {
				fmt.Println(err)
			}
		}()

	}

	if err != nil {
		return false, err
	} else {
		return true, nil
	}

}

If I remove the go func() {}() part and just leave the code in between it seems to execute fine but the moment I add it back it does not execute. Any idea why that is? I initially thought maybe because it's executing on a different thread but this doesn't seem to be the case as I can see on my webservice access logs that it is not executing.

答案1

得分: 4

我认为这种行为是因为函数从不返回到主线程(在启动goroutine之后,程序中没有构造来等待它们完成工作)。
使用通道、IO操作、sync.WaitGroup等可以将控制权交还给主线程。

你可以尝试使用sync.WaitGroup。

示例:https://play.golang.org/p/Zwn0YBynl2

英文:

I think this behaviour is because function never yields back to main thread ( After you launch goroutines, there is no construct in program to wait for them to finish their work).
Use of channels, IO operations, sync.WaitGroup etc can yield control back to the main thread.

You may want to try sync.WaitGroup

Example: https://play.golang.org/p/Zwn0YBynl2

huangapple
  • 本文由 发表于 2016年12月20日 10:04:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/41233835.html
匿名

发表评论

匿名网友

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

确定