Главная страница  Взаимодействие нетривиальных процессов 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 [ 171 ] 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

Глава 3

1. Текст программы приведен в листинге Г. 1.

Листинг Г.1. Вывод идентификатора и порядкового номера слота

svmsg/slotseq.c

1 #inc1ude unpipc.h

2 int

3 mainCint argc, char **argv)

5 int i. msqid;

6 struct msqid ds info;

7 for (i = 0; i < 10; i++) {

8 msqid = Msgget(IPC PRIVATE, SVMSG MODE IPC CREAT);

9 Msgcti(msqid, IPC STAT. &info);

10 printfCmsqid = Xd. seq = 1u\n , msqid, info.msg perm.seq);

11 Msgct!(msqid. IPC RMID, NULL);

12 }

13 exit(O);

14 }

2. Первый вызов msgget задействует первую свободную очередь сообщений, порядковый номер которой имеет значение 20 после двукратного запуска программы из листинга 3.2, и вернет идентификатор 1000. Если предположить, что следующая доступная очередь сообщений никогда ранее не использовалась, ее порядковый номер будет иметь значение О, а возвращаться будет идентификатор 1.

3. Программа приведена в листинге Г.2.

Листинг Г.2. Проверка использования маски создания файла функцией msgget

svmsg/testumask.c

1 #include unpipc.h

2 int

3 main(int argc, char **argv)

5 Msgget(IPC PRIVATE, 0666 IPC CREAT IPCJXCL);

6 umink( /trap/fifo.l );

7 Mkfifo( /tmp/fifo.l , 0666);

8 exit(O);

Запустив эту программу, мы увидим, что маска создания файла имеет значение 2 (снять бит записи для прочих пользователей) и этот бит оказывается снятым для канала FIFO, но не для очереди сообщений:

Solaris X umask 02



Solaris % testumask Solaris % Is -1 /tmp/fifo.l

prw-rw-r-- 1 rstevens otherl 0 Mar 25 16:05 /tmp/fifo.l

Solaris t ipcs -q

IPC status from <running system> as of Wed Mar 25 16:06:03 1998 T ID KEY MODE OWNER GROUP

Message Queues:

q 200 00000000 --rw-rw-rw- rstevens otherl

4. При использовании ftok имеется вероятность того, что для двух полных имен получится один и тот же ключ. При использовании IPC PRIVATE сервер знает, что он создает новую очередь, но в этом случае ему нужно записать ее идентификатор в какой-либо файл, чтобы клиенты могли его считать.

5. Вот один из способов обнаружения коллизий:

Solaris % find / -links 1 -not -type 1 - print xargs -nl ftokl > temp.l Solaris % wc -1 temp.l 109351 temp.l

Solaris % sort +0 -1 temp.l nawk { if (lastkey= $1)

print lastline, $0 lastline = $0 lastkey = $1 ) > temp.2

Solaris % wc -1 temp.2 82188 temp.2

Программа f i nd игнорирует файлы, на которые имеется несколько ссылок (поскольку у всех ссылок одинаковый номер узла), и символические ссылки (поскольку функция stat возвращает информацию для файла, на который ссылка указывает). Большой процент коллизий (75,2%) вызван тем, что в Solaris 2.x используется только 12 бит номера узла. Поэтому в файловых системах с числом файлов более 4096 количество коллизий может быть велико. Например, файлы с номерами 4096, 8192, 12 288 и 16 384 будут иметь один и тот же ключ IPC (если все они принадлежат одной файловой системе).

Мы запустили эту программу в той же файловой системе, но используя функцию ftok из BSD/OS, которая добавляет номер узла к ключу целиком, и получили всего 849 коллизий (менее 1%).

Глава 4

1. Если бы дескриптор fd[l] остался открытым в дочернем процессе при завершении родительского, его операция read для этого дескриптора не вернула бы признак конца файла, потому что дескриптор был бы еще открыт в дочернем процессе. Закрытие fd[l] гарантирует, что после завершения родительского процесса все его дескрипторы закрываются и вызов read для fd[l] возвращает 0.

2. Если поменять местами порядок вызовов, другой процесс сможет создать канал FIFO в промежутке между вызовами open и mkfifo, в результате чего последний вернет ошибку.



3. Если выполнить

Solaris % mainopen 2>temp.stderr

/etc/ntp.conf > /rnyfile Solaris % cat temp.stderr

sh: /rnyfile: cannot create

мы увидим, что рореп срабатывает успешно, но fgets считывает символ конца файла. Сообщение об ошибке записывается интерпретатором в стандартный поток сообщений об ошибках.

5. Измените первый вызов open, указав флаг отключения блокировки:

readfifo - Open(SERV FIFO, 0 RDONLY OJONBLOCK, 0): Возврат из этого вызова произойдет немедленно, как и из следующего вызова open, поскольку канал уже открыт на чтение. Чтобы избежать ошибки при вызове readline, флаг 0 NONBLOCK для дескриптора readfifo следует снять, перед тем как вызывать эту функцию.

6. Если клиент откроет свой канал на чтение перед открытием канала сервера, все зависнет. Единственный способ избежать блокировки заключается в вызове open для этих двух каналов в порядке, показанном в листинге 4.11, или в использовании флага отключения блокировки.

7. Исчезновение пишущего процесса воспринимается считывающим как конец файла.

8. В листинге Г.З приведен текст соответствующей программы.

Листинг Г.З. Возвращает ли fstat количество байтов в канале FIFO?

pipe/testl.c

1 #include unpipc.h

2 int

3 maindnt argc. char **argv)

5 int fd[2];

6 char buff[7]:

7 struct stat info:

8 if (argc != 2)

9 err quit( usage: testl <pathname> ):

10 Mkfifo(argv[l]. FILE MODE):

11 fd[0] OpentargvEl], 0 RDONLY 0 NONBLOCK):

12 fd[l] - Open(argv[l], 0 WRONLY 0 NONBLOCK):

13 /* 4check sizes when FIFO is empty */

14 Fstat(fd[0], &info);

15 printf( fd[0]: st size = ld\n , (long) info.st size):

16 Fstat(fd[l], &info):

17 printf( fd[l]: st size = ld\n . (long) info.st size):

18 Write(fd[l]. buff, sizeof(buff)):

19 Fstat(fd[0]. &info):

20 printf( fd[0]: st size - ld\n . (long) info.st size):

21 Fstat(fd[l], &info):



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 [ 171 ] 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.