ПРИМЕЧАНИЕ
При использовании имени исполняемого файла сервера в качестве аргумента ftok для идентификации какого-либо вида IPC System V обычно передается полное имя этого файла (например, /usr/bin/myserverd), а не часть имени, как сделано у нас (shmget). У нас не возникло проблем в этом примере, потому что все программы запускались из того же каталога, в котором был расположен исполняемый файл сервера. Вы помните, что функция ftok использует номер i-node файла для формирования ключа IPC и ей безразлично, определяется файл своим полным именем или его частью (относительным именем).
На разделяемую память System V накладываются определенные ограничения точно так же, как и на семафоры и очереди сообщений System V (раздел 3.8). В табл. 14.1 приведены значения этих ограничений для разных реализаций. В первом столбце приведены традиционные для System V имена переменных ядра, в которых хранятся эти ограничения.
Таблица 14.1. Типичные значения ограничений, накладываемых на разделяемую память System V
Имя | Описание | DUnix 4.0B | Solaris 2.6 |
---|---|---|---|
shmmax | Максимальный размер сегмента в байтах | 4194304 | 1048576 |
shmmnb | Минимальный размер сегмента разделяемой памяти в байтах | 1 | 1 |
shmmni | Максимальное количество идентификаторов разделяемой памяти в системе | 128 | 100 |
shmseg | Максимальное количество сегментов, подключенных к процессу | 32 | 6 |
Программа в листинге 14.5 определяет значения четырех ограничений, приведенных в табл. 14.1.
//svshm/limits.c
1 #include "unpipc.h"
2 #define MAX_NIDS 4096
3 int
4 main(int argc, char **argv)
5 {
6 int i, j, shmid[MAX_NIDS];
7 void *addr[MAX_NIDS];
8 unsigned long size;
9 /* проверка максимального количества открываемых идентификаторов */
10 for (i = 0; i <= MAX_NIDS; i++) {
11 shmid[i] = shmget(IPC_PRIVATE, 1024, SVSHM_MODE | IPC_CREAT);
12 if (shmid[i]== –1) {
13 printf("%d identifiers open at once\n", i);
14 break;
15 }
16 }
17 for (j = 0; j < i; j++)
18 Shmctl(shmid[j], IPC_RMID, NULL);
19 /* определяем максимальное количество подключаемых сегментов */
20 for (i=0;i <= MAX_NIDS; i++) {
21 shmid[i] = Shmget(IPC_PRIVATE, 1024, SVSHM_MODE | IPC_CREAT);
22 addr[i] = shmat(shmid[i], NULL, 0);
23 if (addr[i] == (void *) –1) {
24 printf("%d shared memory segments attached at once\n", i);
25 Shmctl(shmid[i], IPC_RMID, NULL); /* удаляем неудачно подключенный сегмент */
26 break;
27 }
28 }
29 for (j = 0; j < i; j++) {
30 Shmdt(addr[j]);
31 Shmcfl(shmid[j], IPC_RMID, NULL);
32 }
33 /* проверка минимального размера сегмента */
34 for (size = 1; ; size++) {
35 shmid[0] = shmget(IPC_PRIVATE, size, SVSHM_MODE | IPC_CREAT);
36 if (shmid[0] != –1) { /* выход при успешном создании */