Книга: UNIX: взаимодействие процессов

Пример

Пример

Программа в листинге 11.7 позволяет определить ограничения, приведенные в табл. 11.1.

Листинг 11.7. Определение системных ограничений на семафоры System V

//svsem/limits.c
1   #include "unpipc.h"
2   /* максимальные величины, выше которых ограничение не проверяется */
3   #define MAX_NIDS 4096 /* максимальное количество идентификаторов семафоров */
4   #define MAX_VALUE 1024*1024 /* максимальное значение семафора */
5   #define MAX_MEMBERS 4096 /* максимальное количество семафоров в наборе */
6   #define MAX_NOPS 4096 /* максимальное количество операций за вызов semop */
7   #define MAX_NPROC Sysconf(_SC_CHILD_MAX)
8   int
9   main(int argc, char **argv)
10  {
11   int i, j, semid, sid[MAX_NIDS], pipefd[2];
12   int semmni, semvmx, semmsl, semmns, semopn, semaem, semume, semmnu;
13   pid_t *child;
14   union semun arg;
15   struct sembuf ops[MAX_NOPS];
16   /* сколько наборов с одним элементом можно создать? */
17   for (i = 0; i <= MAX_NIDS; i++) {
18    sid[i] = semget(IPC_PRIVATE, 1, SVSEM_MODE | IPC_CREAT);
19    if (sid[i] == –1) {
20     semmni = i;
21     printf("%d identifiers open at oncen", semmni);
22     break;
23    }
24   }
25   /* перед удалением находим максимальное значение, используя sid[0] */
26   for (j = 7; j < MAX_VALUE; j += 8) {
27    arg.val = j;
28    if (semctl(sid[0], 0, SETVAL, arg) == –1) {
29     semvmx = j – 8;
30     printf("max semaphore value = %dn", semvmx);
31     break;
32    }
33   }
34   for (j = 0; j < i; j++)
35    Semctl(sid[j], 0, IPC_RMID);
36   /* определяем максимальное количество семафоров в наборе */
37   for (i = 1; i <= MAX_MEMBERS; i++) {
38    semid = semget(IPC_PRIVATE, i, SVSEM_MODE | IPC_CREAT);
39    if (semid == –1) {
40     semmsl = i-1;
41     printf("max of %d members per setn", semmsl);
42     break;
43    }
44    Semctl(semid, 0, IPC_RMID);
45   }
46   /* сколько всего семафоров можно создать? */
47   semmns = 0;
48   for (i = 0; i < semmni; i++) {
49    sid[i] = semget(IPC_PRIVATE, semmsl, SVSEM_MODE | IPC_CREAT);
50    if (sid[i] == –1) {
51     /*
52      До этого в наборе было semmsl элементов,
53      но теперь мы уменьшаем количество элементов на 1 и смотрим.
54      не получится ли создать семафор
55     */
56     for (j = semmsl-1; j > 0; j--) {
57      sid[1] = semget(IPC_PRIVATE, j, SVSEM_MODE | IPC_CREAT);
58      if (sid[i] != –1) {
59       semmns += j;
60       printf("max of %d semaphoresn", semmns);
61       Semctl(sid[i], 0, IPC_RMID);
62       goto done;
63      }
64     }
65     err_quit("j reached 0, semmns = %d", semmns);
66    }
67    semmns += semmsl;
68   }
69   printf("max of %d semaphoresn", semns);
70  done:
71   for (j = 0; j < i; j++)
72    Semctl(sid[j], 0, IPC_RMID);
73   /* определяем количество операций за вызов semop() */
74   semid = Semget(IPC_PRIVATE, semmsl, SVSEM_MODE | IPC_CREAT);
75   for (i = 1; i <= MAX_NOPS; i++) {
76    ops[i-1].sem_num = i-1;
77    ops[i-1].sem_op = 1;
78    ops[i-1].sem_flg = 0;
79    if (semop(semid, ops, i) += –1) {
80     if (errno != E2BIG)
81      err_sys("expected E2BIG from semop");
82     semopn = i-1;
83     printf("max of %d operations per semop()n", semopn);
84     break;
85    }
86   }
87   Semctl(semid, 0, IPC_RMID);
88   /* определение максимального значения semadj */
89   /* создание одного набора с одним семафором */
90   semid = Semget(IPC_PRIVATE, 1, SVSEM_MODE | IPC_CREAT);
91   arg.val = semvmx;
92   Semctl(semid, 0, SETVAL, arg); /* устанавливаем значение на максимум */
93   for (i = semvmx-1; i > 0; i--) {
94    ops[0].sem_num = 0;
95    ops[0].sem_op = –i;
96    ops[0].sem_flg = SEM_UNDO;
97    if (semop(semid, ops, 1) != –1) {
98     semaem = i;
99     printf("max value of adjust-on-exit = %dn", semaem);
100    break;
101   }
102  }
103  Semctl(semid, 0, IPC_RMID);
104  /* определение максимального количества структур UNDO */
105  /* создаем один набор с одним семафором и инициализируем нулем */
106  semid = Semget(IPC_PRIVATE, 1, SVSEM_MODE | IPC_CREAT);
107  arg.val = 0;
108  Semctl(semid, 0, SETVAL, arg); /* установка значения семафора в 0 */
109  Pipe(pipefd);
110  child = Malloc(MAX_NPROC * sizeof(pid_t));
111  for (i = 0; i < MAX_NPROC; i++) {
112   if ((child[i] = fork()) == –1) {
113    semmnu = i – 1;
114    printf("fork failed, semmnu at least %dn", semmnu);
115    break;
116   } else if (child[i] == 0) {
117    ops[0].sem_num = 0; /* дочерний процесс вызывает semop() */
118    ops[0].sem_op = 1;
119    ops[0].sem_flg = SEM_UNDO;
120    j = semop(semid, ops, 1); /* 0 в случае успешного завершения. –1 – в случае ошибки */
121    Write(pipefd[1], &j, sizeof(j));
122    sleep(30); /* ожидает завершения родительским процессом */
123    exit(0); /* на всякий случай */
124   }
125   /* родительский процесс считывает результат вызова semop() */
126   Read(pipefd[0], &j, sizeof(j));
127   if (j == –1) {
128    semmnu = i;
129    printf("max # undo structures = %dn", semmnu);
130    break;
131   }
132  }
133  Semctl(semid, 0, IPC_RMID);
134  for (j = 0; j <= i && child[j] > 0; j++)
135   Kill(child[j], SIGINT);
136  /* определение максимального количества записей корректировки на процесс */
137  /* создание одного набора с максимальным количеством семафоров */
138  semid = Semget(IPC_PRIVATE, semmsl, SVSEM_MODE | IPC_CREAT);
139  for (i = 0; i < semmsl; i++) {
140   arg.val = 0;
141   Semctl(semid, i, SETVAL, arg); /* установка значения семафора в 0 */
142   ops[i].sem_num = i;
143   ops[i].sem_op = 1; /* добавляем 1 к значению семафора */
144   ops[i].sem_flg = SEM_UNDO;
145   if (semop(semid, ops, i+1) == –1) {
146    semume = i;
147    printf("max # undo entries per process = %dn", semume);
148    break;
149   }
150  }
151  Semctl(semid, 0, IPC_RMID);
152  exit(0);
153 }

Оглавление книги

Оглавление статьи/книги

Генерация: 0.054. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз