[HN Gopher] Show HN: Neco - Coroutine Library for C
___________________________________________________________________
Show HN: Neco - Coroutine Library for C
Author : tidwall
Score : 41 points
Date : 2024-04-08 17:37 UTC (1 days ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| keepamovin wrote:
| I like how your examples become progressively more comprehensive.
| What was your thinking going into this? How did you design this
| library? i think you wanted something this beautiful and perfect
| to exist, am i right? Or is it also an exercise to develop your
| own understanding? I wouldn't know where to begin with C
| gens/coroutines. Probably I would just fallback on kernel/sys
| calls to suspend and hack from there: yay my function is stopped;
| yay my code has been called again. Are you using setjmp/longjmp?
| plagiat0r wrote:
| I love how simple and elegant is this to use:
| https://github.com/tidwall/neco/blob/main/examples/echo-serv...
|
| I was going to actually implement an echo server for load
| balancer health checks with minimal memory usage, but never
| considered doing it in C but I might just use it! Thank you so
| much.
| dingdingdang wrote:
| Can someone help elucidate why "It's a non-goal for Neco to
| provide a scalable multithreaded runtime, where the coroutine
| scheduler is shared among multiple cpu cores [...]" this library
| even makes sense then? When I use coroutines in Go it is
| invariably in order to make use of more CPU cores when extra
| performance needs to be extracted.
| trebecks wrote:
| the scheduler is probably simpler if coroutines can't bounce
| between cores. you can have a single thread per core that runs
| the scheduler to multiplex a bunch of coroutines on the single
| thread, which lines up with the example linked in the repo to a
| redis clone. redis runs a single thread (i think technically it
| has some multithreading stuff now but that was the model for a
| while) but can concurrently process a bunch of requests like
| when 1 or more requests are blocked on blpop, a pubsub thing,
| xread with block arg given, etc. nginx does something similar
| with forking a process per core that runs single threaded
| (ignore the threading for stuff that reads from disk).
| tidwall wrote:
| Also it is possible to start multiple Neco schedulers in
| different threads, there's an example in the readme.
| trebecks wrote:
| yeah i like this model. then you can use whatever
| synchronization junk you prefer to share state between the
| threads, if you have any.
|
| your library looks well written and clean. thanks for
| sharing.
|
| if anyone else wants to go coroutine spelunking, these were
| interesting to me:
|
| https://github.com/higan-emu/libco/tree/master
|
| https://github.com/Tencent/libco
|
| https://github.com/hnes/libaco
|
| https://kernel.googlesource.com/pub/scm/virt/kvm/qemu-
| kvm/+/...
|
| https://tia.mat.br/posts/2012/09/29/asynchronous_i_o_in_c_w
| i...
|
| https://www.cs.uml.edu/~bill/cs516/context_paper_rse-
| pmt.pdf
| LoganDark wrote:
| Coroutines are still very useful for multitasking even if
| you're not sharing tasks between CPU cores. Other coroutines
| can just execute whenever something would normally block,
| removing the need for multiple threads in the first place.
| samatman wrote:
| Goroutines aren't coroutines. This isn't a nitpick, it's pretty
| essential to understanding the goals and non-goals of Neco.
|
| Coroutines are a control-flow primitive which allows for a lot
| of useful things, including advancing program state while a
| coroutine waits on a syscall, generators, iterators, producer-
| consumer patterns with channels, and combinations of these
| things. They generalize function calls, or structure goto, if
| you prefer.
|
| Some of these applications are glossed as concurrent,
| particularly their use to free the thread when execution
| blocks, but all of them are single-threaded. Goroutines are
| preemptively scheduled, and can be relocated between threads
| transparently. That isn't really a coroutine, which is why they
| have a different name.
|
| The README has some notes on how to use Neco coroutines in a
| multithreaded environment. It's basically how you'd run
| execution paths of multiple function calls on several threads,
| because coroutines are an orthogonal concern to threads.
| dkjaudyeqooe wrote:
| These are stackful coroutines, as opposed to stackless.
|
| Stackful coroutines create a new stack for each coroutine thread
| and save and restore the appropriate registers when switching.
| Stackless coroutines are basically normal C functions that have
| been hacked to save their local variables between calls and use
| gotos (or, notoriously, a switch statement) to resume from where
| they last yielded. Both are very useful in their own way.
|
| This is a great project and I'll be trying it out in my current
| work.
___________________________________________________________________
(page generated 2024-04-09 23:00 UTC)