While trying to implement the Named pipe (e.g. two independent unrelated processes that are using the same shared memory) I keep reading that I’d to use pthread_atfork and atexit.
I’m fully agreeing with the use of mutexes and semaphores — using them we can decide when process A would read/write and when process B would read/write.
But for what reason would I want to use pthread_atfork and threads for that?
EDIT:
An example where not using semaphores would cost dearly :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/times.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <assert.h>
// Simple busy-wait loop to throw off our timing.
void busywait(void)
{
clock_t t1 = times(NULL);
while (times(NULL) - t1 < 2);
}
int main(int argc, char *argv[])
{
const char *message = "Hello World\n";
int n = strlen(message) / 2;
pid_t pid = fork();
int i0 = (pid == 0) ? 0 : n;
int i;
for (i = 0; i < n; i++) {
write(1, message + i0 + i, 1);
busywait();
}
}
Roughly, your pipe-alike structure should be located in shared memory (e.g. obtained by
shm_open) and contain the following members:The read function should basically obtain the mutex, then check whether there’s data available for read, and if not, wait on the condition variable and loop rechecking for data. Once data is found, you’ll need to signal the condition variable if the read made it possible to fit more data in the buffer to wake up a potentially-waiting writer. Copy the data read into a caller-provided buffer then unlock the mutex.
The write function should basically obtain the mutex, then check whethere there’s space in the buffer left to write. If not, it should wait on the condition variable and loop rechecking for space available to write. Once space is found, it should copy the data into the buffer, signal the condition variable to wake any reader that might be waiting for data, and unlock the mutex.
Both the mutex and condition variable need to be created with the process-shared attribute it you’ll be using the “pipe” for communication between processes (not just threads in the same process). You probably also need to think about whether you want to support multiple readers/writers and whether you need single-signal or broadcast-signal semantics for the condition variables. There are a lot of ways to optimize the behavior, but the above outline should give you a general starting point.