Hi folks, I've mailed Owen, and he says that while he's done some prep, he doesn't mind me posting something re: IPC.
So. IPC stands for interprocess communication, and it refers to the problem of managing tasks which need more than one process. The two main issues are synchronization (not treading on each other's toes) and data transfer. These are the potential solutions: - Files (existence is a 0-1 var) - Database (assuming it provides table locking) - Semaphores and shared memory - Various kinds of socket (UNIX, TCP/IP, UDP/IP)
Most programmers will have used all of these (except shared memory) at some point. Data transfer is a well understood problem, and one to which there are many well-documented solutions. Synchronization, as it is called, is the devil. I'm only going to describe IPC using semaphores and shared memory, since this is what I know, but it isn't much of a thought extension to see how it can be done with database locking Imagine the following situation, where P1 and P2 are processes running at the same time. P1 is a _producer_, and P2 is a _consumer_. buf is a shared variable; ignore implementation for now (sticking shared in front does not work).
shared int buf;
P1 for (int n = 0; n < 5; n++) { buf = n; }
P2 for (int n = 0; n < 5; n++) { printf("%d: %d", n, buf); }
That producer/consumer relationship looks fine and dandy. However, the CPU is not always shared amongst processes in strict rotation. If either process gets to do an extra loop, data will be lost. To prevent this, the processes must be _synchronized_ before they access the shared variable. _Semaphores_ are special small numbers (usually only 0 and 1 are used) which can be tested and set _atomically_. This means the operation will not be interrupted, enabling it to be used safely for synchronization.
shared int buf; semaphore buf_lock = 0;
P1 for (int n = 0; n < 5; n++) { /* block until lock is available (0). testNset sets the semaphore to 1, and returns the old value */ while (testNset(&buf_lock) != 0) ; /* actual write */ buf = n; /* reset lock (jargon for set to 0) */ reset(&buf_lock) }
P2 for (int n = 0; n < 5; n++) { while (testNset(&buf_lock) != 0) ; /* block until lock gained */ printf("%d: %d", n, buf); reset(&buf_lock) /* unlock */ }
Actually obtaining semaphores and shared variables (IE a chunk of shared memory) is a little more difficult than it looks above. It isn't too hard to work out from the following manpages: semget, semctl, semop, shmget, shmctl, shmat, shmdt. If anyone is interested, I think I still have the C++ interface I wrote.
A more complicated example I figured out for a unit last year is to allow a block of shared memory to be read by multiple processes, but only written to by a single writer (with no reads happening at the time). The above implementation doesn't allow more than one reader at once. I can't remember how it goes, unfortunately, but I can dig it out for anyone who's very interested. Incidentally, locks are usually called mutexes, short for mutual exclusion.
Alexis -- Attention. "The only Zen you find on the tops of mountains is the Zen you bring up there." - RM Pirsig "I find that the harder I work, the more luck I seem to have" - T Jefferson