Am 07.03.2014 22:11, schrieb Bienlein:
One question - doesn't Vibe.d already use green threads?
What they are saying on their web site is that they are using fibers and
at the same time they say they are using libevent. That is confusing for
me. On http://vibed.org/features they write: "Instead of using classic
blocking I/O together with multi-threading for doing parallel network
and file operations, all operations are using asynchronous operating
system APIs. By default, >>libevent<< is used to access these APIs
operating system independently."
Further up on the same page they write: "The approach of vibe.d is to
use asynchronous I/O under the hood, but at the same time make it seem
as if all operations were synchronous and blocking, just like ordinary
I/O. What makes this possible is D's support for so called >>fibers<<".
It does. Bienlein has a very vague knowledge of topics he
comments about.
I thought the vibe.d guys would shed some light at this at the occasion,
but no luck. What I don't understand is how fibers can listen to input
that comes in through connections they hold on to. AFAIKS, a fiber only
becomes active when it's call method is called. So who calls the call
method in case a connection becomes active? That is then again a kernel
thread? How does the kernel thread know something arrived through a
connection? It can't do a blocking wait as the system would run out of
kernel threads very quickly.
Sorry, I've been busy with some non-programming business over the past
days and didn't have a chance to reply. Making a small article about the
internal workings of the task/fiber system is planned for a long time
now, but there are so many items with higher priority that it
unfortunately hasn't happened so far. See my reply [1] in the other
thread for a rough outline.
I think what Go and Erlang do is to use green threads (or equivalent,
goroutines in Go) for the applications side and a kernel thread pool
within the runtime doing "work stealing" on the green threads. This is
more or less (ish) what the Java Fork/Join framework of Doug Lea does as
well.
When in Go a channel runs empty the scheduler detaches the thread that
served it and attaches it to a non-empty channel. In Go all this is in
the language and the runtime where it can be done more efficiently than
in a library. AFAIU, this is a main selling point in Go.
I actually don't see a reason why it can't be just as efficient when
done as a library. Taking the example of vibe.d, fibers are currently
never moved between threads (although technically, they could), but they
are still stored in a free list and reused for later tasks. There is not
much more overhead than a few variable assignments and the fiber context
switches.
Vert.x is caliming to be able to handle millions of active connections.
All right, as you can't have millions of threads on the JVM they must do
that through some asynchronous approach (I guess Java NewIO). I read
that an asynchronous solution is not as fast as one with many blocking
threads as in Go or Erlang. I don't understand why. It was just claimed
that this were the case.
AFAIK they use a combination of callback based asynchronous I/O (mostly
for server applications) combined with a thread pool for parallelizing
synchronous I/O (mostly for client type applications/tasks). So it's
basically a hybrid system that still makes a lot of trade-offs between
performance and comfort. Disclaimer: this statement is based only on
looking at a few examples and maybe a bog post, I don't have any first
hand experience with vert.x.