[<<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 }