Пример
Пример
Программа в листинге 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 once ", 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 = %d ", 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 set ", 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 semaphores ", 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 semaphores ", 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() ", 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 = %d ", 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 %d ", 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 = %d ", 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 = %d ", semume);
148 break;
149 }
150 }
151 Semctl(semid, 0, IPC_RMID);
152 exit(0);
153 }
Данный текст является ознакомительным фрагментом.