M:N threading is not, from a developer perspective, the same thing as coroutines/fibers. Coroutines are lower-level; it's possible to build something like M:N threading on top of coroutines, but it means doing a lot of work that's already done for you in a language that provides M:N threading out of the box, and if you have to do it yourself, that also means code you use from others isn't going to integrate well with it generally.
Not sure I understand what you're trying to say here, this sounds exactly backwards to my reading. A green threading library can be written in assembly language with no reference to anything but the hardware ISA specification and the ABI that defines the relevant calling convention. It's as "low level" as a software construct can be. The only lower level implementation I can think of are hardware-assisted context switching features like you see on some embedded architectures.
Coroutines, on the other hand, are artifacts of the language runtime and depend in sensitive ways on that whole stack. Much higher level.
The exact sense of the phrase you excerpted is explained in the next clause of the same sentence of the comment.
Honestly I was asking the question because I thought you had some deeper point in mind I couldn't see. But you just had it backwards.
If it's about serving a great number of concurrent connections, I'm not sure why M:N is the only way to go.
What M:N threading does, at least in theory, is allows you to create 100,000 threads cheaply AND keep a slow function call in one thread from blocking others. In a language with those features you can build it out of continuations (NOT coroutines) and real threads. But that requires building your own scheduler that can move a user thread to a different process at need. Which is non-trivial, and is unlikely to cooperate well with any third party libraries.
That said, whether M:N threading is a real optimization depends on a ton of things. A big one is the underlying performance of the scheduler and the language. Which is improving for Perl 6..but has a long way to go.
Whether optimizing at this level matters is another good question. Most companies shouldn't care. Those that should, should be cautious about deploying Perl 6 into a mature infrastructure.
So that's why people can think that M:N is important, and why you might legitimately disagree.
When the author (as is the case here with M:N threading) identifies the specific feature of interest, we do know exactly what it means, independently of whether they also reference something less precise.
> If it's about serving a great number of concurrent connections, I'm not sure why M:N is the only way to go.
If you want to posit an argument challenging the idea that M:N threading is an advantage, that's a different thing that disagreeing with the authors contention that choices are fairly limited if you want a language with language-level integration of M:N threading.
I much prefer the go/erlang version of this. Playing the "what color is your function" game or "will it block" is no fun.
This was quite painful with.js Node 1-2yrs back when Promises and coroutines started picking up steam [such as https://github.com/tj/co]. It was always a shot in the dark.
Has this situation changed now? (basically is the stdlib all async friendly now?)
https://github.com/ruby-concurrency/concurrent-ruby for those wondering. Rails uses it as of version 5.
Now, I preferred correction to downvoting, but I can easily see why others would choose downvoting.
It's probably just my age, as I started out online when most discussion forums lacked explicit voting mechanisms. Before social media came along, and "gamified" human conversation. Maybe it helps police trolls, but at the cost of encouraging group-think and excessive meme-referencing, and just making a lot of people more neurotic and insecure in general. Overall, I think that online discussion is worse than it was 15 years ago, due to the psychological effects of all the imaginary Internet points.
But anyhoo, at the time I saw this (45 minutes after my original comment), my comment had 25 votes and was the top-most thing on this page. More often than not, if you wait an hour, the crowd straightens out the impact of any early outliers.
> But anyhoo, at the time I saw this (45 minutes after my original comment), my comment had 25 votes and was the top-most thing on this page.
It was grayed out at the bottom of the page when I saw it.
Sometimes there is some really weird voting dynamic here and it would be interesting to know what goes on.
For a lack of a better word you can call it intellectual curiosity or something.
Many times it's because the user was just asking a question, or made what they thought was a perfectly reasonable comment.
HN is pretty horrible with voting etiquette.
And I'll still hold that this is acceptable curiosity.
Like dragonwriter said, having coroutines in your language or a fiber library is not close to the same thing as the language having a scheduler that maps those fibers onto native threads for you. Some of the languages mentioned can't even execute multiple threads on multiple cores in parallel.
A more accurate statement is: "python bytecode can't execute concurrently w/o something like multiprocessing". The key difference? You can do multithreaded I/O all day long, which is a pretty important use case of threading. You can also hand off work to C and release the GIL, although this isn't as common. Example: XML parsing, regex, numeric work.
FWIW all these gotchas are one of the reasons I love just having complete threading support built in to my language.
No this isn't any more accurate. Python bytecode does execute concurrently if you have multiple threads. It just doesn't execute in parallel.
> [Erlang] is a concurrent language – by that I mean that threads are part of the programming language, they do not belong to the operating system. That's really what's wrong with programming languages like Java and C++. It's threads aren't in the programming language, threads are something in the operating system – and they inherit all the problems that they have in the operating system. One of the problems is granularity of the memory management system. The memory management in the operating system protects whole pages of memory, so the smallest size that a thread can be is the smallest size of a page. That's actually too big.
> If you add more memory to your machine – you have the same number of bits that protects the memory so the granularity of the page tables goes up – you end up using say 64kB for a process you know running in a few hundred bytes.
With Erlang, there are threads running concurrently across multiple CPU's and a preemptive scheduler within each of those threads. This is all transparent through use of Erlang processes. Essentially, many concurrent schedulers managing hundreds of thousands of processes that start out at 0.5kb each. A JVM thread is 1024kb by comparison and a goroutine is 2kb.
You're getting legitimate concurrency with Erlang, as well as isolation. There are only so many things that a single CPU can do at the same time and that's where the scheduler becomes necessary. The scheduler also ensure that if you fire off 100,000 processes and one of them is CPU intensive that it can't hog the processor and preventing the others allocated to that processor from executing.
For example, I have to explicitly install 2.7 to be able to use Cocos2d-x build scripts.
Jython and IronPython are both limited to Python 2.x, ZipPy is WIP without a stable release.
Because for some people, it's not enough to think of others as misinformed, or not so well-spoken.
They need to be thought of as blundering idiots, and castigated accordingly.
Putting aside the "web scale" jokes (http://www.mongodb-is-web-scale.com/), this statement is still absurd.
Every major language, or at least the ones that matter for backend development, has support for thread multiplexing / coroutines / fibers, whatever. Perhaps not in the core language syntax or standard library. But it's easy to implement with native code, and so SOMEONE has implemented it in a library if the language has an FFI.
Java, and all of the other JVM-based languages in turn, have Quasar (http://docs.paralleluniverse.co/quasar/).
Ruby has support for primitive fibers baked into the standard language (https://ruby-doc.org/core-2.1.1/Fiber.html), and likewise community gems with more robust functionality like Quasar.
Python 3 likewise has this out of the box (https://www.python.org/dev/peps/pep-0492/).
The list goes on and on: https://en.wikipedia.org/wiki/Coroutine#Programming_language....