TDC368 UNIX and Network Programming Camelia Zlatea, PhD Week 6: Inter-Process Synchronization Signals Lock-Files
UNIX Network Programming – TDC Page 2 Spring 2003 Discussion File Redirectation Inter-process Communication via pipe –Pipe synchronization –Deadlock? »A deadlock situation can occur when two processes open respectively the two ends of a pipe for writing –Starvation? »Blocking reader / writer for unbounded interval of time –Errors »“Broken Pipe”? SIGPIPE –Process Type »Related process(named or unamed pipes) »Unrelated process (only named pipes) Pipe vs. File for inter-process communication?
UNIX Network Programming – TDC Page 3 Spring 2003 I/O redirection - ex: sort result #include int main(void) { int fd1, fd2; switch (fork()) { case -1: perror("fork"); break; case 0: if ((fd1 = open("test.dat", O_RDONLY))==1) || (fd2 = open("results", O_WRONLY|O_CREAT|O_TRUNC,0644))==-1) { perror("open failure"); _exit(errno); } /* set standard input from "test.dat" */ if (dup2(fd1,0)==-1) _exit(errno); /* set standard output to "results" */ if (dup2(fd2,1)==-1) _exit(errno); close(fd1); close(fd2); execl("sort","sort"); perror("execl"); exit(errno); } return 0; }
UNIX Network Programming – TDC Page 4 Spring 2003 Simulating sleep by using alarm and pause #include void wakeup() { ; }; unsigned int sleep ( unsigned int timer ) { if (sigset(SIGALRM, wakeup)==-1) { perror("sigset"); return 1; } (void)alarm( timer ); (void)pause(); return 0; }
UNIX Network Programming – TDC Page 5 Spring 2003 Example: A Producer-Consumer relation int main(void) { int fd, n, i; pid_t pid, ppid; char buf[1]; if((fd=open("/tmp/data_file", O_APPEND|O_CREATE, 0640)) <0) exit(1); sigset(SIGTERM,SIG_IGN);/* signal */ ; sigset(SIGINT,SIG_IGN); /* signal */ pid=fork(); switch (pid) { case -1: { perror(“FORK”); exit(1); } case 0: /* child process - Producer */ sigset(SIGUSR1,wakeup); sighold(SIGUSR1); /* block / hold signals SIGUSR1 until sigpause*/ for (i=0; i<=100; i++) { /* sleep a random amount of time */ n = (int)(getpid()%256); srand((unsigned)n); sleep(rand() %5); /* writes a character in file */ sprintf(buf,"%d",i); write(fd, buf,sizeof(buf)); fprintf(stderr,"Producer PID=%d value = %d\n",getpid(), i); ppid=getppid(); kill(ppid, SIGUSR2); sigpause(SIGUSR1);/* pause(); until SIGUSR! received*/ } break; void wakeup() { ; };
UNIX Network Programming – TDC Page 6 Spring 2003 Example: A Producer-Consumer relation default: /* -parent code - Consumer */ sigset(SIGUSR2,wakeup); sighold(SIGUSR2); /* block / hold signals SIGUSR2 until sigpause*/ for (i=0; i<=100; i++) { /* sleep a random amount of time */ n = (int)(getpid()%256); srand((unsigned)n); sleep(rand() %5); sigpause(SIGUSR2); /* pause(); */ /* reads a character from file */ read(fd, buf,sizeof(buf)); fprintf(stderr,"Consumer PID=%d value=%d\n",getpid(),atoi(buf)); kill(pid, SIGUSR1) } break; } exit(0); }
UNIX Network Programming – TDC Page 7 Spring 2003 Provide a mechanism to share data among processes Provide a mechanism to synchronize reading and writing of shared files. Applicable for regular files A process imposes a lock on a file(or record) so that other processes can’t modify the file(record) until it is unlocked by the process. UNIX File/Record Locking
UNIX Network Programming – TDC Page 8 Spring 2003 UNIX File/Record Locking write lock –exclusive lock –processes are prevented from setting any overlapping read/write locks on the locked region of the file read lock –shared lock –processes are prevented from setting any overlapping write locks on the locked region of the file
UNIX Network Programming – TDC Page 9 Spring 2003 mandatory lock –enforced by OS kernel –example: chmod a+l file_name an erroneous situation: A process sets a mandatory lock on a file and never unlocks it. The file cannot be accessed by any other process until the owner process is either killed or system is re-booted UNIX File/Record Locking
UNIX Network Programming – TDC Page 10 Spring 2003 advisory lock –processes can still use read or write to access the shared file unless cooperation procedure is followed processes using advisory locks to share a file must cooperate: –try to set a lock on the record to be accessed (read or write) –if fails to set the lock then: »wait and test_again or »do_work and test_again –if succeeds to set the lock »accesses the locked file/record »releases the lock UNIX File/Record Locking
UNIX Network Programming – TDC Page 11 Spring 2003 System V 4 and POSIX.1 #include int fcntl(int fd, int cmd,struct flock fl); cmd: –F_SETLK »sets a file lock; »do not block if failure –F_SETLKW »sets a file lock »blocks until succeeds –F_GETLK »tests if a file or record is locked and by whom UNIX File/Record Locking
UNIX Network Programming – TDC Page 12 Spring 2003 System V 4 and POSIX.1 struct flock { shortl_type; /* lock type */ shortl+whence; /* rec. ref. */ off_tl_start; /* rec. offset */ off_tl_len; /* rec.length */ pid_tl_pid; /* process ID*/ }; UNIX File/Record Locking
UNIX Network Programming – TDC Page 13 Spring 2003 System V 4 and POSIX.1 /* lock type */ F_RDLCK - read/shared lock F_WRLCK - write/exclusive lock F_UNLCK - unlock a record/file /* record reference */ SEEK_CUR - current file pointer SEEK_SET - byte 0 of file SEEK_END - EOF UNIX File/Record Locking
UNIX Network Programming – TDC Page 14 Spring 2003 Simulating Semaphores with Lock Files int Pflag(char *file_name, int ntries, int nsec) { int fd; i=0; while ((fd = create(file_name,0)) ==-1 && errno ==EACCES) /* EACCES - file exists, no write permission on it */ if (++i <ntries) sleep(nsec); else return 0; close(fd); /* lock_file created with 0 bytes and no permissions */ if (fd == -1) return 0; else return 1; }
UNIX Network Programming – TDC Page 15 Spring 2003 Simulating Semaphores with Lock Files int Vflag(char *file_name) { int i; i = unlink(file_name); if (i==0) return 1; /* success, lock file removed */ if (i==-1) return 0; /* failure, lock file was not removed */ }
UNIX Network Programming – TDC Page 16 Spring 2003 Process Synchronizations using Lock Files int main(void) { pid_t p; int i; q, status, nbytes; int fd; char buf[80]; /* parent process opens date file Shared Data File */ if ((fd = open("/tmp/data_file", O_RDONLY|O_CREATE, 0666))<0) { perror("open"); exit(1); } /* parent forks 3 new processes */ for (i=0; i<4; i++) { if (p=fork()) == 0) break; } switch (p) { case 0:/* a child process */ if (Pflag("/tmp/lock_file", 5,10)) { if (nbytes=read(fd,buf,sizeof(buf)))>0) { fprintf(stderr,"PID=%d data=%s\n", getpid(), buf); sleep(10); /* releases the resource - shared file */ Vflag("/tmp/lock_file"); } else fprintf(stderr, "Cannot access data file\n"); break;
UNIX Network Programming – TDC Page 17 Spring 2003 Process Synchronizations using Lock Files case -1:/* cannot fork processes */ perror("fork"); exit(1); break; default:/* parent */ while ((q=wait(&status))>0) ; break; } exit(0); }