Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

They tried green threads years and years ago in Java and then reversed course, and M:N was also a thing on NetBSD years ago. I wonder why Go is working where the others went away from it?


> I wonder why Go is working where the others went away from it?

Quite frankly, because Go developers don't learn from other's mistakes and reinvent square wheels.

Kernel threads will always be better and faster than usermode threads.

This is because any inefficiency in threading comes from the scheduler. Your usermode scheduler will always necessarily be slower and worse; it just makes so much sense to put your scheduling code where your context switching and process isolation code already is.

Sure, you can get a short-term gain by iterating fast and testing code if kernel developers are too slow and/or unwilling; but then eventually your code will get merged into the kernel anyways once you're done. So really usermode threads are only good as a rapid prototyping tool, not something for serious use.


>Quite frankly, because Go developers don't learn from other's mistakes and reinvent square wheels.

Your response doesn't even start on the right foot, since Java never used green threads for performance and therefore is not a good place to hedge this argument at. Citation needed if you're going to start with that.

You can also go ahead and insult the Erlang developers for Processes since they did it first:

http://erlang.org/doc/reference_manual/processes.html

>This is because any inefficiency in threading comes from the scheduler. Your usermode scheduler will always necessarily be slower and worse; it just makes so much sense to put your scheduling code where your context switching and process isolation code already is.

You know, a Go context switch doesn't hit the kernel. It's not more expensive than a kernel context switch. I don't know why you'd think it is. Why not inline scheduling to the process where it knows what's blocked on what?

>Sure, you can get a short-term gain by iterating fast and testing code if kernel developers are too slow and/or unwilling; but then eventually your code will get merged into the kernel anyways once you're done. So really usermode threads are only good as a rapid prototyping tool, not something for serious use.

You can hold your breath for threads to become cheaper than goroutines, but careful not to suffocate. A goroutine pretty much just needs a stack, 4kb. The kernel thread has structures, well, in the kernel, for paging, for the task itself, and the stack structure is bigger (think you can at least adjust that though.)

And as for integrating the Go GC into the scheduler... I'd love to see what Linus's thoughts on merging that to kernel are!

Doesn't matter if you just have a few thousand threads but that's a limiting way to look at something. RabbitMQ can have processes all over the place for everything and have more processes than you could ever have threads and it remains among best in class for performance.


Goroutines only have a 2kb initial stack since 1.4, AFAIK? It was originally 4kb, then 8kb to avoid split stacks, then back to 2kb, I think?


The Go concurrency model can't possibly be implemented in the kernel because it trades some isolation guarantees for better performance.


I am pretty sure Java's historical use of green threads was an issue of portability and not performance. They used traditional threading primitives. Java's decision to use green threads may have actually made a lot of sense in an era when consumer computers typically only had one physical thread to begin with.

Go on the other hand is based on CSP principles and a threading model that looks like actors. The threading model is deeply ingrained in the language, and it is designed around it. Goroutines are very cheap in Go, and the scheduler is fairly effective because it knows what threads to wake when - it's not blind. Goroutines are scheduled across n threads, not just a single OS thread, so they can take good advantage of multicore or multi CPU systems. This design does hurt C interoperability a bit, but imo it's greatly worth it.

Go is not the only language that works this way. I believe its concurrency model was inspired a lot by Erlang with its 'processes' model.


The reason why this gets more attention in Go than elsewhere is because it's unusual for the kind of language Go is (lot lower level than something like Erlang). Everything else in Go is really "better C so long as it's not C++", but goroutines are an experiment in their own right.


From what I recall, Java didn't switch because it didn't work. I think it switched because the green threads were built on what Solaris supported, and they moved to full OS threading to support Windows, Linux, Mac etc.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: