[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 Разделяемая память - Порожденный процесс

Родительский процесс создает три подпроцесса. Каждый из них будет
продавать места, подсчитываемые переменной в разделяемой памяти.
Семафор позволяет избежать одновременных попыток изменения счетчика.
16-20          Проверяет правильность числа аргументов

22        Напоминаем, что  родитель использовал  в качестве  ключа при
          создании разделяемого  сегмента  IPC_PRIVATE.  Идентификатор
          разделяемого сегмента передается как аргумент exec(2). Здесь
          он должен быть преобразован назад из ASCII в целое число.

23        Отображает  разделяемый   сегмент  в  адресное  пространство
          процесса.

28        Получает  идентификатор   семафора  из  аргумента  командной
          строки.

29        Продает места,  пока счетчик  оставшихся мест  (хранящийся в
          разделяемой памяти) не станет нулевым.

30        Отсоединяет разделяемый сегмент.
               РАЗДЕЛЯЕМАЯ ПАМЯТЬ - ПОРОЖДЕННЫЙ ПРОЦЕСС
  1 #include"registration.h"
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 #include<sys/types.h>
  5 #include<sys/ipc.h>
  6 #include<sys/sem.h>
  7 #include<sys/shm.h>
  8 #include<stdio.h>
  9 static struct CLASS*class_ptr;
 10 static char    *pname;
 11 static intshmid, semid, ret;
 12 static struct sembuf lock ={ 0, -1, 0};
 13 static struct sembuf unlock ={ 0, 1, 0};
 14 static void sell_seats(void),rpterror(char*);

 15 main(int argc, char *argv[])
 16 {
 17 if(argc < 3){
 18 fprintf(stderr,"Usage:%s shmid semid\n",argv[0]);
 19 exit(1);
 20 }
 21 pname = argv[0];
 22 sscanf(argv[1], "%d", &shmid);
 23 class_ptr = shmat(shmid, 0, 0);
 24 if(class_ptr == (struct CLASS *) -1){
 25 rpterror("shmat failed");
 26 exit(2);
 27 }
 28 sscanf(argv[2], "%d", &semid);

 29 sell_seats();

 30 ret = shmdt(class_ptr);
 31 exit(0);
 32 }

36-60          Каждые десять секунд или меньше пытается продать место.
          Вызов semop  в строках  40 и 53 гарантируют, что только один
          процесс  в   каждый  момент   изменяет  разделяемую   память
          (переменную  seats_left).   Когда  не  осталось  мест,  цикл
          заканчивается.  Это   приводит  к   возврату  из  функции  и
          завершению программы.

61-66          Функция rpterror()  добавляет имя  процесса  к  строке,
          которая затем передается библиотечной функции perror(3C).

Файл: shmc.c

 36 static void sell_seats(void){
 37 int all_out = 0;
 38 srand( (unsigned)getpid());
 39 while ( !all_out ){ /*loop to sell all seats*/
 40 if(semop(semid,&lock,1) == -1){
 41 rpterror("semop lock failed");
 42 exit(4);
 43 }
 44 if (class_ptr->seats_left > 0){
 45 class_ptr->seats_left--;
 46 printf("%s SOLD SEAT -- %2d left\n",
 47      pname,class_ptr->seats_left);
 48 }
 49 else{
 50 all_out++;
 51 printf("%s sees no seats left\n", pname);
 52 }
 53 ret = semop(semid,&unlock,1);
 54 if (ret == -1) {
 55 rpterror("semop unlock failed");
 56 exit(4);
 57 }
 58 sleep( (unsigned)rand()%10 + 1);
 59 }
 60 }

 61 static void rpterror(char *string)
 62 {
 63 char errline[50];
 64 sprintf(errline,"%s %s", string, pname);
 65 perror(errline);
 66 }