Call for discussion?
Hi,I just finished studying the GCD PDF from Apple, http://developer.apple.com/mac/library/documentation/General/Conceptual/ConcurrencyProgrammingGuide/Introduction/Introduction.html ,
and reread Hoare's book on CSP,
And long ago (perhaps more than 10 years ago) I studied John Reppy's "Concurrent Programming in ML",
and promptly implemented his notion of channels in Lisp.
All of this has tickled some deeper thinking about multi-threaded code, Erlang-like languages, and problem solving in general.
There is an example of using Hoare's simple unbuffered channels to connect threads (a vast number of them) for computing primes using connected pipelines of filters attached to a simple integer generator. This seems hugely heavy-handed to me. The same kind of processing pipeline for primes and series has been illustrated several times in Scheme using lazy streams (SICP, and John Houston).
Reppy solved some of the problems inherent in Hoare's limited notion of unbuffered channels, and created functionally composable channel primitives to produce a very elegant system that handles normal and abnormal communications. For example, a select on multiple channels, accepting on one, and transparently providing a NAK on the remaining channels so that their sources can perform tear-down and cleanup code in lieu of communicating with the receiving thread.
But throughout Reppy's implementation, he uses threads on each end of communicating channels. Same with Erlang et al (Termite, Butterfly, others...).
In an era of SMP with multiple cores, Apple's GCD has taken the view that there are units of work to be performed, either sequentially, or concurrently, and the OS manages the assignment of work units to available cores. They do this by providing work queues to the programmer, and they wish to discourage the proliferation of threads. And as we all know, with the exception of the Erlang fibers (tiny threads), using threads is a heavy handed approach, just short of using multiple-processes. And there are practical limits imposed by the computer on just how many threads can be running productively.
I find in my own Butterfly implementation that a slew of service threads get spun off, sitting mostly idle until their service is requested.
It would seem that Apple is on to something here. Conventional threads could be viewed as merely one manner of implementing work-channels. Another approach is to forego thinking in threads and use the GCD work queues. A third approach would be to view a channel as merely another calling protocol for functions. One could probably develop a hierarchy of CLOS classes that implement any of these approaches and the calling function would be none wiser regarding the actual implementation.
I like Reppy's functional formalism, but in light of Apple's GCD, one is hardly required to utilize threads to implement his composable channels.
I'm thinking of re-casting my Butterfly system into a higher-level system that ignores overt threads and instead offers services through "channels", distributed arbitrarily across the network. The details of each kind of channel should be of no concern to the service requestor:
kinds of channel providers:
1. in-process functions
2. threads connected by mailboxes
3. processes in the same host, connected by shared interprocess memory buffers
4. processes distributed across the network connected by sockets
Any takers for a deeper discussion?
Dr. David McClain