#include #include #include #include #include #define CHILDREN 5 /* This is just a proof of concept. In a production implementation * you would have proper error checking and loop on EINTR (among many * other improvements). */ static void create_lock(int l[2]) { assert(pipe(l) >= 0); assert(write(l[1], "", 1) == 1); } static void destroy_lock(int l[2]) { assert(close(l[0]) >= 0); assert(close(l[1]) >= 0); } static void lock(int l[2]) { char c; assert(read(l[0], &c, 1) == 1); } static void unlock(int l[2]) { assert(write(l[1], "", 1) == 1); } int main() { int l[2]; pid_t p[CHILDREN]; create_lock(l); for(int n = 0; n < CHILDREN; ++n) { if(!(p[n] = fork())) { lock(l); printf("child %d has lock\n", n); sleep(1); printf("child %d releasing...\n", n); unlock(l); _exit(0); } } for(int n = 0; n < CHILDREN; ++n) while(waitpid(p[n], 0, 0) < 0) ; return 0; }