libmill - Go-style concurrency in C
libmill.org
libmill.org
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.
There's another library linked that has similar functionality with a less go-like API.
Just a guess.
Edit: this has been better discussed elsethread.
> ...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.
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/Transputer ³ https://en.wikipedia.org/wiki/XMOS
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?
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).
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).
Go can somewhat emulate Actor model using concurrency control structures and buffered channels with non-blocking send to emulate mailboxes.
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)
libthread was written as a replacement when Alef was abandoned in Plan 9 3rd edition
Do you have a link to this?
May 10, 2019 - https://news.ycombinator.com/item?id=19879679 (76 comments)
Nov 18, 2015 - https://news.ycombinator.com/item?id=10585505 (83 comments)
(and 2 more with 1 comment)
libdill:
9 months ago - https://news.ycombinator.com/item?id=27357295 (19 comments)
Feb 17, 2018 - https://news.ycombinator.com/item?id=16401234 (22 comments)
Dec 21, 2017 - https://news.ycombinator.com/item?id=15977983 (50 comments)
June 4, 2016 - https://news.ycombinator.com/item?id=11835091 (32 comments)
https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
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.
Do you have a pointer to Mashey's comments on Mill?
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.
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 messonly 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
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.
They wrote a macro (or in this case a set of macros) to transform that into valid C code.