from MessagingAsAlternativeToMultiThreading:
The key here is non-blocking. If the single thread ever gets stuck then everything stops. Therefore there are implicitly a minimum of two fundamental threads required. One is blockable (allowing one to do non-deterministic operations like while loops), and the other is a non-blocking watchdog which breaks out of long/stuck processes. A single thread cannot guarantee this sort of behaviour unless you severely limit the kind of operations you can do i.e. no non-fixed loops including recursion. Fully elaborated you end up with preemptive multitasking with timeouts and interrupts i.e. a real-time operating system. --RichardHenderson
Erlang opts for a single thread, non-blocking system calls, and a restricted programming style to make sure nothing runs for unbounded time. The restriction is that at each "step" you have to increment a counter, and if it reaches a maximum then you have to schedule out. For Erlang code the counter is automatically incremented on each function call (which works for loops, since they implemented as recursive function calls), for built-in C code it has to be incremented manually. -- LukeGorrie
Technically one need not write code for multiple threads in order to arrange for interruption of non-deterministic loops. User-space code under UNIX and similar (e.g. Linux, QNX, etc) systems can, for example, register a signal handler for SIGALARM and call for a later alarm to be generated.