Goroutine仅在执行fmt.Println时有效

Yeh*_*tan 1 concurrency go goroutine

出于某种原因,当我删除fmt.Printlns然后代码阻塞.我不知道为什么会这样.我想要做的就是实现一个简单的并发限制器......

我从来没有经历过这么奇怪的事情.这就像fmt冲刷变量或其他东西并使其工作.

此外,当我使用常规函数而不是goroutine时,它也可以工作.

这是以下代码 -

package main

import "fmt"

type ConcurrencyLimit struct {
    active int
    Limit  int
}

func (c *ConcurrencyLimit) Block() {
    for {
        fmt.Println(c.active, c.Limit)
        // If should block
        if c.active == c.Limit {
            continue
        }
        c.active++
        break
    }
}

func (c *ConcurrencyLimit) Decrease() int {
    fmt.Println("decrease")
    if c.active > 0 {
        c.active--
    }
    return c.active
}

func main() {
    c := ConcurrencyLimit{Limit: 1}
    c.Block()
    go func() {
        c.Decrease()
    }()
    c.Block()
}
Run Code Online (Sandbox Code Playgroud)

澄清:尽管我接受了@kaedys的回答(这里)@Kaveh Shahbazian(这里)回答了一个解决方案

Kae*_*dys 7

你没有c.Decrease()机会跑. c.Block()运行一个无限的for循环,但它永远不会阻塞for循环,只是continue在每次迭代时反复调用.主线程无限循环使用100%.

但是,当您添加一个fmt.Print()调用时,会生成一个系统调用,允许其他goroutine运行.

这篇文章详细介绍了goroutines如何产生或被抢先一步.但请注意,它稍微过时了,因为现在输入一个函数有一个随机的机会将该线程传递给另一个goroutine,以防止类似的样式泛滥线程.