#include #include #include #include #include #include #include #include int enter_critical (int fd) { struct flock lock_info; lock_info.l_type = F_WRLCK; lock_info.l_whence = SEEK_SET; lock_info.l_start = lock_info.l_len = 0; int status; while ( (status = fcntl(fd,F_SETLKW,&lock_info)) == -1 && errno == EINTR ) { // reconstruct lock_info: lock_info.l_type = F_WRLCK; lock_info.l_whence = SEEK_SET; lock_info.l_start = lock_info.l_len = 0; } if (status == -1) perror("enter_critical"); return status; } int exit_critical (int fd) { struct flock lock_info; lock_info.l_type = F_UNLCK; lock_info.l_whence = SEEK_SET; lock_info.l_start = lock_info.l_len = 0; int status; while ( (status = fcntl(fd,F_SETLKW,&lock_info)) == -1 && errno == EINTR ) { // reconstruct lock_info: lock_info.l_type = F_UNLCK; lock_info.l_whence = SEEK_SET; lock_info.l_start = lock_info.l_len = 0; } if (status == -1) perror("exit_critical"); return status; } void test1(int lock1) { // we create three processes: if(fork() == 0) { if(fork() == 0) { // nephew = `process 1' printf("Process 1 enters critical 1 (%d)\n", enter_critical(lock1)); sleep(3); printf("Process 1 exits critical 1 (%d)\n", exit_critical(lock1)); } else { // child = `process 2' printf("Process 2 enters critical 1 (%d)\n", enter_critical(lock1)); sleep(3); printf("Process 2 exits critical 1 (%d)\n", exit_critical(lock1)); } } else { // parent = `process 3' printf("Process 3 enters critical 1 (%d)\n", enter_critical(lock1)); sleep(3); printf("Process 3 exits critical 1 (%d)\n", exit_critical(lock1)); } } void test2 (int lock1, int lock2) { // we create two processes: if(fork() == 0) { // child = `process 1' printf("Process 1 enters critical 1 (%d)\n", enter_critical(lock1)); sleep(1); printf("Process 1 enters critical 2 (%d)\n", enter_critical(lock2)); sleep(3); printf("Process 1 exits critical 2 (%d)\n", exit_critical(lock2)); printf("Process 1 exits critical 1 (%d)\n", exit_critical(lock1)); } else { // parent = `process 2' printf("Process 2 enters critical 2 (%d)\n", enter_critical(lock2)); sleep(1); printf("Process 2 enters critical 1 (%d)\n", enter_critical(lock1)); sleep(3); printf("Process 2 exits critical 2 (%d)\n", exit_critical(lock2)); printf("Process 2 exits critical 1 (%d)\n", exit_critical(lock1)); } } int main (int argc, char** argv) { char lock1name[256], lock2name[256]; snprintf(lock1name,255,"/tmp/lock-%d-1",getpid()); snprintf(lock2name,255,"/tmp/lock-%d-2",getpid()); int lock1 = open(lock1name,O_WRONLY|O_CREAT|O_APPEND,S_IRWXU|S_IRWXG|S_IRWXO); int lock2 = open(lock2name,O_WRONLY|O_CREAT|O_APPEND,S_IRWXU|S_IRWXG|S_IRWXO); if (lock1 == -1 || lock2 == -1) { perror("Cannot create locks"); return 1; } //test1(lock1); test2(lock1,lock2); // clean up close(lock1); close(lock2); unlink(lock1name); unlink(lock2name); }