#include #include #include #include #include #include #include #define array_size 1000 /* no of elements in shared memory */ //extern char *shmat(); void P(int *s); void V(int *s) ; int main(){ int shmid, s, pid; /* shared memory, semaphore, proc id */ char *shm; /*shared mem. addr returned by shmat()*/ int *a, *addr, *sum; /* shared data variables*/ int partial_sum; /* partial sum of each process */ int i; /* initialize semaphore set */ union semun { int val; struct semid_ds *buf; unsigned short int *array; struct seminfo *__buf; } su; int init_sem_value = 1; su.val = 1; s = semget(IPC_PRIVATE, 1, (0600 | IPC_CREAT)); if (s == -1) { /* if unsuccessful*/ perror("semget"); exit( 1 ); } /* if (semctl(s, 0, SETVAL, init_sem_value) < 0) { */ if (semctl(s, 0, SETVAL, su) < 0) { perror("semctl") ; exit ( 1 ) ; } /* create segment*/ shmid = shmget(IPC_PRIVATE, (array_size*sizeof(int)+1), (IPC_CREAT | 0600)) ; if (shmid == -1) { perror("shmget") ; exit (1) ; } /* map segment to process data space */ shm = shmat(shmid, NULL, 0); /* returns address as a character*/ if (shm == (char*)(-1)) { perror("shmat"); exit(1); } addr = (int*)shm; /* starting address */ sum = addr; /* accumulating sum */ addr++; a = addr; /* array of numbers, a[] */ *sum = 0; for (i = 0; i < array_size; i++) /* load array with numbers */ *(a + i) = i+1; pid = fork() ; /* create child process */ if (pid == 0) { /* child does this */ partial_sum = 0; for (i = 0; i < array_size; i = i + 2) partial_sum += *(a + i); } else { /* parent does this */ partial_sum = 0; for (i = 1; i < array_size; i = i + 2) partial_sum += *(a + i); } P(&s) ; /* for each process, add partial sum */ *sum += partial_sum; V(&s) ; printf("\nprocess pid = %d, partial sum = %d\n", pid, partial_sum); if (pid == 0) exit(0); else wait(0); /* terminate child proc */ printf("\nThe sum of 1 to %i is %d\n", array_size, *sum) ; /* remove semaphore */ if (semctl(s, 0, IPC_RMID, 1) == -1) { perror("semctl") ; exit ( 1 ) ; } /* remove shared memory */ if (shmctl(shmid, IPC_RMID, NULL) == -1) { perror("shmctl"); exit ( 1 ) ; } /* end of main */ return 0; } void P(int *s) /* P(s) routine*/ { struct sembuf sembuffer, *sops; sops = &sembuffer; sops->sem_num = 0; sops->sem_op = -1; sops->sem_flg = 0; if (semop(*s, sops, 1) < 0) { perror("semop") ; exit( 1 ) ; } return; } void V(int *s) /* V(s) routine */ { struct sembuf sembuffer, *sops; sops = &sembuffer; sops->sem_num = 0; sops->sem_op = 1; sops->sem_flg = 0; if (semop(*s, sops, 1) <0) { perror("semop"); exit ( 1) ; } return; }