To understand go scheduler I wrote this simple code
https://gist.github.com/anonymous/bc2d650c736f195be358. Without the line where I call runtime.LockOsThread() it works as I expect, ie I can run this code on 2 cores and it will block on CPU bound goroutines, this is because there is no place where context switch could happen. Also no IOBound goroutine will be run.
Now as the docs states:
LockOSThread wires the calling goroutine to its current operating system thread. Until the calling goroutine exits or calls UnlockOSThread, it will always execute in that thread, and no other goroutine can.
From my understanding IOBound goroutine should be bind to its own dedicated core so no CPUBound goroutine should still CPU from it and allow it to run, but it doesn't happen. Why?
Bonus questions, what are your best practices on writing go applications performing hard CPU bound operations with need of having low latency for IO tasks also. My solution would be to create a pool of CPU bound workers binded to its own CPUs so other IO tasks could perform with no blocking, though it doesn't seems to me like it is the go way.