[HN Gopher] libmill - Go-style concurrency in C
___________________________________________________________________
libmill - Go-style concurrency in C
Author : graderjs
Score : 139 points
Date : 2022-03-16 15:16 UTC (7 hours ago)
(HTM) web link (libmill.org)
(TXT) w3m dump (libmill.org)
| MisterTea wrote:
| Prior art:
|
| http://man.postnix.pw/plan_9/2/thread (Plan 9's thread(2).
| Personal note: I absolutely LOVE working with this library)
|
| https://swtch.com/libtask/ (Rus Cox's portable library (Someone
| on the 9fans mailing list ported it to a micro-controller))
|
| See Also:
|
| https://seh.dev/go-legacy/ (A nice code tour of the historical
| CSP lineage of Go)
|
| https://swtch.com/~rsc/thread/ (Bell Labs and CSP Threads)
| s-video wrote:
| >Someone on the 9fans mailing list ported it to a micro-
| controller
|
| Do you have a link to this?
| bakul wrote:
| Probably this one: https://9fans.topicbox.com/groups/9fans/Te
| f717f57ede82d4f-M5...
| ck45 wrote:
| libthread is great, although I somehow wish that the
| programming language Alef won in some alternate universe.
|
| libthread was written as a replacement when Alef was abandoned
| in Plan 9 3rd edition
| bakul wrote:
| libthread is available as part of plan9port on Unix systems.
| jjtheblunt wrote:
| why not just use Go, since it's a modern day lovechild of C and
| Scheme, with a very smart compiler?
| jayar95 wrote:
| There's a lot of C out there homie
| didip wrote:
| @dang needs to bust out his prior submission script here. libmill
| and libdill has been posted a lot on Hacker News.
| Jtsummers wrote:
| Only two with significant comments:
|
| May 10, 2019 - https://news.ycombinator.com/item?id=19879679
| (76 comments)
|
| Nov 18, 2015 - https://news.ycombinator.com/item?id=10585505
| (83 comments)
| heinrichhartman wrote:
| Here is the full list:
|
| https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
| hu3 wrote:
| Previous post was 10 months ago?
|
| https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
| moltke wrote:
| Without go's nested functions and variable capture it's really
| not the same. The best use for channels in go (IMO) is to use
| variable scope checking to keep people new to the codebase from
| messing with resources outside of the right threads. You put all
| the critical code in a nested function and pass it over the
| channel, viola the compiler helps make sure your program is
| correct.
| [deleted]
| Shadonototra wrote:
| That is why i love C, you can model it to do whatever you want,
| it truly empowers you to program your PC
| Findecanor wrote:
| It isn't pure C. It uses x86-64 assembly language to save
| register context.
|
| It falls back to setjmp()/longjmp() when its not x86-64, but
| (contrary to popular belief) those don't actually save all the
| registers, and longjmp() will on some platforms terminate the
| program if it detects it being abused in this way.
| pjmlp wrote:
| Same could have been done in Modula-2 or Object Pascal, to name
| just two among many, including the Assembly and setjmp/longjmp
| parts.
| ibraheemdev wrote:
| The follow up to this library was libdill, the library that I
| believe originally introduced structured concurrency:
| http://libdill.org/structured-concurrency.html
| synergy20 wrote:
| "Technically, these are the differences: Libdill is idiomatic
| C. Whereas libmill takes Go's concurrency API and implements it
| in an almost identical manner in C, libdill tries to provide
| the same functionality via a more C-like and POSIX-like API."
| marcofiset wrote:
| Why not call this for what it is? It's CSP in C. Go is not the
| only language in which CSP is used as the concurrency model.
|
| I understand using "Go-style" as an adjective to describe this
| makes it easier for the uninitiated but it's doing everyone a
| disservice IMHO.
| intrepidhero wrote:
| I'm very much a novice in concurrent programming so I looked
| that up:
| https://en.wikipedia.org/wiki/Communicating_sequential_proce...
|
| > ...communicating sequential processes (CSP) is a formal
| language for describing patterns of interaction in concurrent
| systems. > ... based on message passing via channels.
|
| That seems like a mathematical language that could describe
| goroutines and channels but also seems like it could describe
| python's multiprocessing and queue constructs. I think of those
| as very different things given the (vastly different)
| applications. When I think of "go-style" I think of lightweight
| threads (I can have 1000s), where as python processes are heavy
| (100 is pushing it?). So maybe the specifics of the
| implementation have as much to do with the go-style as the
| abstract concept?
|
| My understanding here is fuzzy for sure and I welcome
| corrections and more detail.
| jlokier wrote:
| There are no queues in CSP, although you can make one by
| making a queue process.
|
| In CSP, the sending side of a message is always logically
| simultaneous with the receiving side. So it's like Go's
| default channels where the sender and receiver both block
| until ready to transfer, and different from Python's
| multiprocessing and queue constructs, where the sender
| doesn't block.
|
| CSP was used in Occam1 on Transputers2 in the 1980s. In
| Occam, it was normal to have a large number of tiny
| processes, some of them maybe only a few instructions (such
| as an implementation of a queue), and the thread switching
| and communication primitives were actual CPU instructions.
| The CPUs were joined with dedicated message communication
| links into large meshes, providing hardware parallelism with
| a very different model than today's SMP multi-core. A similar
| architecture exists today, XMOS3.
|
| Go implements a model similar to CSP on today's SMP multi-
| core systems and OSes, emphasising many efficient, small
| threads running loops that communicate synchronously.
| Channels are unbuffered by default, making them like CSP.
| They can be made buffered, which adds a queue, as if a CSP
| queue process was added. Go is much less rigid than Occam,
| because you can also make new channels and spawn new threads
| efficiently, which are essential features in modern sofware.
|
| Python multiprocessing doesn't provide efficient, small
| threads. You need larger thread units to get good performance
| out of it. It also emphasises queuing. So it's quite
| different from CSP.
|
| Erlang implements a model like Occam and Go of many,
| efficient, small threads, but the messaging is always
| asynchronous. The communication is similar to Go with
| buffered channels.
|
| 1 https://en.wikipedia.org/wiki/Occam_(programming_language)
| 2 https://en.wikipedia.org/wiki/Transputer 3
| https://en.wikipedia.org/wiki/XMOS
| zucker42 wrote:
| Looks like it is "go-style" because the API/syntax is modelled
| after the go API. In particular the "choose" macro from the
| example looks to be designed to mimic "select" even though
| otherwise macros might be dispreferred.
|
| There's another library linked that has similar functionality
| with a less go-like API.
|
| Just a guess.
| yakubin wrote:
| I think Concurrent ML (1991) had select before Go. Go itself
| took it from Newsqueak (1994) and Limbo (1995) I think. The
| name itself probably comes from the UNIX select(2) syscall,
| which first appeared in 4.2BSD (1983).
| stingraycharles wrote:
| As someone who worked with a decent variety of languages that
| all claim their fame to CSP (Erlang, Clojure and Go), suffice
| to say that these all look very similar. It's the tooling
| _around_ the CSP where the real differences are.
| [deleted]
| gpderetta wrote:
| Isn't erlang closer to actors than CSP? I.e. no rendez-
| vous.
|
| Edit: this has been better discussed elsethread.
| aidenn0 wrote:
| Libdill[1] is the structured concurrency (i.e. CSP) library by
| this author. Libmill is specifically trying to look as much
| like Go as possible.
|
| 1: http://libdill.org/
| [deleted]
| adrusi wrote:
| Well it's specifically CSP using cooperative multitasking
| (sadly no multithreading support unlike go) and a go-like API.
| CSP is a lot less specific than that.
| mmcgaha wrote:
| I think because many people's first exposure to CSP was in go,
| go-style-concurrency has become the crescent wrench of CSP.
| freedomben wrote:
| Interesting, I didn't realize CSP was so specific.
|
| I heard someone say that Erlang's model was CSP too. They
| aren't called "channels" but they're very similar in that you
| have two different process/threads that are reading/writing
| to/from an ordered stream that feels the same as
| reading/writing to/from a Go channel.
|
| What would Erlang's model be called? Does "the Actor Model"
| cover it?
| Jtsummers wrote:
| Yes, Erlang is based more on the actor model.
|
| CSP is synchronous, so sending to a channel will block if the
| receiver isn't ready. Erlang and actors are asynchronous in
| this matter. They will send regardless of whether the
| receiver is in a state where it can receive the message.
| Practically, Go (and libmill) allow buffered channels so that
| you only block if the channel's buffer is full.
|
| CSP is based on anonymous processes. Actors have identity,
| and this would be the process IDs in Erlang. Erlang and the
| actor model don't use channels (though you can use processes
| to mimic them).
| freedomben wrote:
| Nice, thanks that makes a lot of sense and definitely an
| important difference.
| masklinn wrote:
| > Practically, Go (and libmill) allow buffered channels so
| that you only block if the channel's buffer is full.
|
| Go also allows rendezvous channel (channels with an empty
| buffer, so either side can only proceed when the other
| arrives: the actual message exchange is synchronous).
| qbasic_forever wrote:
| This looks great! A port to microcontroller platforms like
| Arduino would be really slick IMHO.
| pjmlp wrote:
| Or given that Arduino uses C++, just use co-routines instead.
| ta-nehdjebdh wrote:
| Also possibly of interest here:
| https://github.com/wingo/fibers/wiki/Manual
___________________________________________________________________
(page generated 2022-03-16 23:01 UTC)