-1

Regarding this post As that post mentioned, we don't need to put runtime.Gosched() anymore, since Go 1.15

But I still got the issue in Go 1.19. Concisely,

  • I don't use runtime.Goshed()
  • I used runtime.GOMAXPROCS(2)

If I put runtime.Ghoshed(), it work flawlessly. But without that, it seems Go executes a goroutine entirely before move to another.

Here is the code

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

func main() {
    runtime.GOMAXPROCS(2)

    go say("Hello")
    say("World")
    time.Sleep(time.Second)
}

Output (this seems cooperative, not preemptive )

Hello
Hello
Hello
Hello
Hello
World
World
World
World
World

Expected something like this

Hello
World
Hello
World
Hello
World
Hello
World
Hello

My CPU

fmt.Println(runtime.NumCPU())
Output: 12
  • no https://stackoverflow.com/questions/13107958/what-exactly-does-runtime-gosched-do – Para Mar 22 '23 at 03:30
  • Try that with two goroutines and an endless for-loop, and you can see. – Burak Serdar Mar 22 '23 at 03:43
  • 1
    "Do we still need runtime.Gosched() in go 1.19?" No. Especially as we never really _needed_ to call Gosched() in any sensible, non-pathological, real code. – Volker Mar 22 '23 at 05:48
  • 1
    Can you submit an answer for that? instead of putting comments like that? – Huey Bui Mar 22 '23 at 06:36
  • "we don't need to put runtime.Gosched() anymore, since Go 1.15" I think you meant to say "since Go 1.5" – Jonathan Hall Mar 22 '23 at 09:21
  • You are right, that's a typo – Huey Bui Mar 22 '23 at 09:32
  • "preemtive" does not mean switching context at every single line of execution, that would be horribly inefficient. Print more output and you will see it alternating, but that still has nothing to do with changes in preemption, since any function call has always been a possible yield point for goroutines. And since you are setting `runtime.GOMAXPROCS(2)` it's not even the go runtime managing this, the OS is scheduling the individual threads. – JimB Mar 22 '23 at 13:20

1 Answers1

-1

We don't need to put runtime.Gosched() anymore. Your test gives you the illusion that one thread runs and then executes another thread. This is because your cpu runs faster. You can simply add a sleep, and the output of the test will be a normal concurrent output.

package main
import "fmt"
import "time"
//import "runtime"

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

func main() {
    //runtime.GOMAXPROCS(2)

    go say("Hello")
    say("World")
    time.Sleep(10*time.Second)
}
feiniks
  • 28
  • 3