/* ** File: semlock.c ** ** Author: Edward Chow ** ** */ #include #include #include #include #include #include #include #include #include #include union semun { int val; /* value for SETVAL */ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ unsigned short int *array; /* array for GETALL, SETALL */ struct seminfo *__buf; /* buffer for IPC_INFO */ }; int semID; /* ID of the semaphore set. */ union semun sem_val; /* semaphore value, for semctl(). */ union semun sem_val2; /* semaphore value, for semctl(). */ char* shm_addr; /* address of shared memory segment. */ int shm_id; /* ID of the shared memory segment. */ int *sticky_num; /* # of sticky entries in shared mem */ int *shm_cpid; int *shm_taskid; struct timeval stv, etv; struct timezone tz; int cnt; /* number of packets to read */ int debug = 0; #define MAXMSG 4096 void P(int sem_id, int number) { struct sembuf lock_it; lock_it.sem_num = number; lock_it.sem_op = -1; lock_it.sem_flg = 0; semop(sem_id, &lock_it, 1); printf("***Semaphore number=%d decremented by one (locked)\n", number); } void V(int sem_id, int number) { struct sembuf unlock_it; unlock_it.sem_num = number; unlock_it.sem_op = 1; unlock_it.sem_flg = 0; semop(sem_id, &unlock_it, 1); printf("***Semaphore number=%d incremented by one (unlocked)\n", number); } void do_it() { int time; int cpid; int taskid; int j = 0; P(semID, 0); taskid= ++(*shm_taskid); cpid= ++(*shm_cpid); V(semID, 0); printf("cpid=%d taskid=%d\n", cpid, taskid); printf("This is child proces #%d\n", cpid); do { P(semID, 0); taskid= ++(*shm_taskid); V(semID, 0); printf("cpid=%d assigned task=%d\n", cpid, taskid); time = (int) random()%5+1; printf("cpid=%d sleep time=%d sec.\n", time); sleep(time); j++; } while (taskid <= 10 && j<10); printf("cpid=%d done its tasks, exit\n", cpid); exit(0); } int main(int argc, char* argv[]){ int time; int taskid, cpid; int i; int rc; (void) gettimeofday(&stv, &tz); /* create shared memory segment */ shm_id = shmget(IPC_PRIVATE, MAXMSG, IPC_CREAT | IPC_EXCL | 0600); if (shm_id == -1) { (void) fprintf(stderr,"Unable to allocate shared memory\n"); exit(1); } /* attach the shared memory segment to our process's address space. */ shm_addr = shmat(shm_id, NULL, 0); if (!shm_addr) /* operation failed. */ { (void) fprintf(stderr,"Error: unable to attach the shared memory to our process's address space\n "); exit(1); } /* create a semaphore */ semID = semget(IPC_PRIVATE, 2, IPC_CREAT | 0600); if (semID == -1) { (void) fprintf(stderr,"Error: unable to create a semaphore\n"); exit(1); } /* intialize the semaphore to '1'. */ sem_val.val = 1; rc = semctl(semID, 0, SETVAL, sem_val); if (rc == -1) { (void) fprintf(stderr,"Error: unable to initialize semaphore number 0"); exit(1); } sem_val.val = 3; rc = semctl(semID, 1, SETVAL, sem_val); if (rc == -1) { (void) fprintf(stderr,"Error: unable to initialize semaphore number 1"); exit(1); } shm_taskid = (int *) shm_addr; shm_cpid = (int *) shm_addr+4; *shm_cpid = 0; /* set shared variables */ *shm_taskid = 0; for (i=1; i<4; i++) { if (fork()== 0) { do_it(); } } /* use wait instead P(semID, 1); */ for (i=1; i<4; i++) { int status; wait(&status); } printf("all children done! Parent Exit\n"); }