6 ms·
libmill - Go-style concurrency in C
- ibraheemdev 5y agoThe follow up to this library was libdill, the library that I believe originally introduced structured concurrency: http://libdill.org/structured-concurrency.html http://libdill.org/structured-concurrency.html
- synergy20 5y ago"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 5y agoWhy 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.
- zucker42 5y agoLooks 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.
- stingraycharles 5y agoAs 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 5y ago[deleted]
- gpderetta 5y agoIsn't erlang closer to actors than CSP? I.e. no rendez-vous. Edit: this has been better discussed elsethread.
- yakubin 5y agoI 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).
- adrusi 5y agoWell 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 5y agoI think because many people's first exposure to CSP was in go, go-style-concurrency has become the crescent wrench of CSP.
- intrepidhero 5y agoI'm very much a novice in concurrent programming so I looked that up: https://en.wikipedia.org/wiki/Communicating_sequential_processes 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 5y agoThere 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 Occam¹ on Transputers² 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, XMOS³. 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. ¹ https://en.wikipedia.org/wiki/Occam_(programming_language) https://en.wikipedia.org/wiki/Occam_(programming_language) ² https://en.wikipedia.org/wiki/Transputer https://en.wikipedia.org/wiki/Transputer ³ https://en.wikipedia.org/wiki/XMOS https://en.wikipedia.org/wiki/XMOS
- freedomben 5y agoInteresting, 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 5y agoYes, 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).
- masklinn 5y ago> 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).
- freedomben 5y agoNice, thanks that makes a lot of sense and definitely an important difference.
- paskozdilar 5y agoTechnically, Erlang is based on Actor model. But both models are formally equivalent, i.e. you can simulate one model in another. Go can somewhat emulate Actor model using concurrency control structures and buffered channels with non-blocking send to emulate mailboxes.
- deleted 5y ago[deleted]
- aidenn0 5y agoLibdill[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/ http://libdill.org/
- paskozdilar 5y agoGo is (I think?) the first popular language that's CSP oriented. Just like many Actor model languages are often referred to as "Erlang-style".
- rubenbe 5y agoThere is even the xcore cpu by xmos has CSP support in hardware.
- qbasic_forever 5y agoThis looks great! A port to microcontroller platforms like Arduino would be really slick IMHO.
- pjmlp 5y agoOr given that Arduino uses C++, just use co-routines instead.
- ta-nehdjebdh 5y agoAlso possibly of interest here: https://github.com/wingo/fibers/wiki/Manual https://github.com/wingo/fibers/wiki/Manual
- MisterTea 5y agoPrior art: http://man.postnix.pw/plan_9/2/thread 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/ 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/ https://seh.dev/go-legacy/ (A nice code tour of the historical CSP lineage of Go) https://swtch.com/~rsc/thread/ https://swtch.com/~rsc/thread/ (Bell Labs and CSP Threads)
- ck45 5y agolibthread 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
- s-video 5y ago>Someone on the 9fans mailing list ported it to a micro-controller Do you have a link to this?
- bakul 5y agolibthread is available as part of plan9port on Unix systems.
- Shadonototra 5y agoThat is why i love C, you can model it to do whatever you want, it truly empowers you to program your PC
- Findecanor 5y agoIt 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.
- Shadonototra 5y agoIt is, i had this piece of code in mind: choose { out(ch, int, 42): foo(); in(ch, int, i): bar(i); otherwise: baz(); end } every other languages are too rigid when it comes to DSLs, so you either fall back to a scripting language / bloated XML file, or you use the language itself and write a bloaty and unreadable mess only C allows that kind of level of customization, so powerful i love D, i use it more than C, but damn i miss being able to shape the language this way
- throw_m239339 5y ago> every other languages are too rigid when it comes to DSLs, so you either fall back to a scripting language / bloated XML file, or you use the language itself and write a bloaty and unreadable mess C macros fuckery aren't a good thing, at all. The problem aren't macro per say, Rust has them, the problem is the way they are implemented, with basic text substitution. There is absolutely nothing to praise here. > every other languages are too rigid when it comes to DSLs, so you either fall back to a scripting language This is objectively a false statement, Crystal, Rust, Haxe... actually implement Macros the right way. C macros are brittle and a horror to debug.
- Jtsummers 5y ago
- didip 5y ago@dang needs to bust out his prior submission script here. libmill and libdill has been posted a lot on Hacker News.
- Jtsummers 5y agoOnly two with significant comments: May 10, 2019 - https://news.ycombinator.com/item?id=19879679 https://news.ycombinator.com/item?id=19879679 (76 comments) Nov 18, 2015 - https://news.ycombinator.com/item?id=10585505 https://news.ycombinator.com/item?id=10585505 (83 comments)
- pflanze 5y agoJuly 25, 2015 - https://news.ycombinator.com/item?id=9947749 https://news.ycombinator.com/item?id=9947749 (16 comments) (and 2 more with 1 comment) libdill: 9 months ago - https://news.ycombinator.com/item?id=27357295 https://news.ycombinator.com/item?id=27357295 (19 comments) Feb 17, 2018 - https://news.ycombinator.com/item?id=16401234 https://news.ycombinator.com/item?id=16401234 (22 comments) Dec 21, 2017 - https://news.ycombinator.com/item?id=15977983 https://news.ycombinator.com/item?id=15977983 (50 comments) June 4, 2016 - https://news.ycombinator.com/item?id=11835091 https://news.ycombinator.com/item?id=11835091 (32 comments)
- heinrichhartman 5y agoHere is the full list: https://hn.algolia.com/?dateRange=all&page=0&prefix=true&query=libmill&sort=byPopularity&type=story https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
- hu3 5y agoPrevious post was 10 months ago? https://hn.algolia.com/?dateRange=all&page=0&prefix=true&query=libdill%7Clibmill&sort=byDate&type=story https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
- moltke 5y agoWithout 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.
- jjtheblunt 5y agowhy not just use Go, since it's a modern day lovechild of C and Scheme, with a very smart compiler?
- jayar95 5y agoThere's a lot of C out there homie
- nicklaf 5y agoI'd be fascinated if you'd like to elaborate on the Scheme part of that!
- jjtheblunt 5y agoLexical closure of syntactic lambdas, with escape analysis as an implementation optimization.
- deleted 5y ago[deleted]
- rurban 5y agoif you click on past you'll see the past 9 discussions in the last 8 years. it's not entirely new, and nothing changed since
- waste_monk 5y agoOff-topic but the name reminded me: Whatever happened to the Mill CPU architecture / Mill Computing? I've just realised I haven't heard anything about it for a while, and just looking on The Mill forum the last post was nearly two months ago.
- KerrAvon 5y agoDidn’t RISC-V put the final nail in the Mill CPU coffin? (I think Mashey put the first nail in decades ago?)
- therealcamino 5y agoRISC-V is a pretty evolutionary architecture when compared to the Mill architecture, so I would think they're attempting pretty different things. I don't know a lot about Mill other than what I've read recently, but it seems like it's just had extremely slow progress towards an implementation, which leaves the claims about it's architectural innovations not proven until there's a chip to prove them on. Do you have a pointer to Mashey's comments on Mill?
- pabs3 5y agoI've mentioned Mill recently in some threads and the responses were that it has always been vaporware. https://news.ycombinator.com/item?id=30522481 https://news.ycombinator.com/item?id=30522481
- aidenn0 5y agoThey just don't seem to be in a rush to get anything to market; I know they are talking to VCs but don't get the impression that they are motivated to take money that would speed their time-to-market.
- XorNot 5y agoThis is cool. I have no idea what I would ever use it for, but its been bookmarked for me.
- omginternets 5y agoHow does that ‘choose’ statement work? Did they just extend the C syntax?
- Jtsummers 5y agohttps://github.com/sustrik/libmill/blob/e8937e624757663f5379018cae3f2b3e916afb6c/libmill.h#L324 https://github.com/sustrik/libmill/blob/e8937e624757663f5379... They wrote a macro (or in this case a set of macros) to transform that into valid C code.