3 ms·
I think the part about cooperative/preemptive multitasking isn't saying it all. Go multitasking is based on the compiler inserting switchpoints on function cal
by giovannibajo1 10y ago
I think the part about cooperative/preemptive multitasking isn't saying it all.
Go multitasking is based on the compiler inserting switchpoints on function calls and syscall boundaries. But this affects the scheduling of a single OS-level threads executing that specific goroutine. The number of OS-level threads that the Go scheduler uses can arbitrarily grow, and OS-level threads are preemptively multitasked.
So I think the description is focusing a narrow view of the problem. What is usually required by applications is low latency in reply to system events (e.g.: data available on network sockets), and Go performs very well in this context. For instance, the fact that Go is transparently using a epoll/kqueue based architecture under the hood is probably affecting latency much more than the whole "cooperative" issue as depicted.
- eternalban 10y ago> I think the part about cooperative/preemptive multitasking isn't saying it all. That's still not the entire story: GC & tight loops in Go: https://github.com/golang/go/issues/10958 https://github.com/golang/go/issues/10958 Per process vs per runtime GC: https://news.ycombinator.com/item?id=12043088 https://news.ycombinator.com/item?id=12043088
- deleted 10y ago[deleted]
- eternalban 10y agoCan't update parent. Please /do not/ read my OP as a dig/boost at any level. Just pure geek interest in language architectures and sharing info.
- solidsnack9000 10y agoWhen you say "the number of threads that the Go scheduler uses can arbitrarily grow..." is it not set by GONUMPROCS or something like that? Or is it a dynamic thing -- new threads appear as needed? The cooperative issue is simply that until a thread does become free, the application can not respond to an event -- even given the epoll/kqueue architecture you describe.
- giovannibajo1 10y agoNo, those are the "procs". In Go scheduler's lingo, there are three different concepts: * "G": these are goroutines * "M": these are OS-level threads (the ones I was mentioning). These are bounded by debug.SetMaxThreads (default: 10000). * "P": these are basically locks that Ms must acquire to run Go code. These are bounded by GOMAXPROCS. So when you way "GOMAXPROCS=2", you're saying "I want at most two Gs executing code simultaneously", but you can still have a very high number of OS-level threads that are I/O blocked. Notice that when a G does a blocking I/O there are two possibilities: if it's a pollable operation, the handle is passed to the epoll/kqueue thread, the M releases its P and is recycled to do something else. If it's a non-pollable operation, the M releases the P but stays allocated to wait for the operation to finish (e.g.: the syscall to return). At that point, given that at least one P is free, any ready G can be scheduled, but a new M might be needed.