I am well used to relying on GHC's forkIO
for portable lightweight threads when programming in Haskell.
What are equivalent libraries for C that can provide the same scalibility and ease of use?
Specifically I need C-equivalents of at least the following two functions.
forkIO :: IO () -> IO ThreadId
killThread :: ThreadId -> IO ()
I assume for my application, it would be enough if threads only switched on blocking operations rather than being forcefully suspended because all threads block highly frequently for network IO and I only use the splice
system call to ask the Linux kernel to push data around between sockets.
Update
This paper has figures and tables comparing
with results favoring Protothreads. As I have not used any and there may also be other libraries, I would love to hear from anyone who has used / developed such libraries.
Use POSIX threads. They are "green" on any modern implementation, not in the sense of "Green Threads", but in the sense of being lightweight and efficient. There is no portable way to roll your own threads on top of plain C or POSIX minus threads. As OP mentioned, there are some libraries implementing green-threads/co-routines in non-portable ways (often despite claiming portability).
The closest-to-portable approach is using
makecontext
/swapcontext
, and unfortunately this cannot perform well because it has to make syscalls to save/restore the signal mask on each switch between "threads". This makes switching between "green" threads more expensive than a context switch between kernel-level threads on a "real" POSIX threads implementation, and basically negates any claimed benefit of "green threads".Non-portable approaches that don't care about the signal mask could use machine-specific asm to do the context switches entirely in userspace, and in theory perform better than kernel-level threads, but performance would again fly out the window as soon as you introduce IO, since a thread that's about to perform IO would have to first do expensive tests to check if the operation will block, and if so, turn over control to a different thread.
I maintain my position that "green threads" are an idea whose time is long past. This also seems to be the position of the Austin Group (responsible for POSIX), who removed the
ucontext
functions in POSIX 2008 and recommended replacement with POSIX threads (which are now a mandatory feature).