У. Стивенс , Взаимодействие процессов
Исходники всех примеров для этой книги от Стивенса лежат тут
Исходники для этой страницы лежат тут
Глава 1 : Обзор средств взаимодействия процессов UNIX
Методы передачи сообщений в порядке их хронологического порядка можно разделить
на группы :
1. Каналы - pipes и fifo (именованные каналы) .
Pipe работает только в связке родительский процесс - дочерний процесс .
Fifo работает между любыми процессами .
2. Очереди стандарта System V queue
3. Очереди сообщений Posix message queue
4. Удаленный вызов процедур - remote ptocedure calls - RPC
Формы синхронизации развивались в следующем порядке :
1. Блокировка записей - locking
2. Семафоры System V semaphores , а также shared memory
3. Семафоры POSIX POSIX semaphores и shared memory
4. Взаимные исключения mutex и условные переменные conditional variables
5. Блокировка чтения-записи - read-write locks
Стандарт потоков POSIX Pthreads был принят в 1995 году .
У всех потоков общие глобальные переменные .
По продолжительности жизни обьекты IPC можно разделить на 3 группы :
1. Process-persistent - обьект живет до тех пор , пока живут процессы , в которых он задействован
К ним относятся pipe , fifo , mutex
2. Kernel-persistent - живет до перезагрузки ядра или до явного его удаления
К ним относятся queue , семафоры , shared memory
3. Filesystem-persistent - дивет до тех пор , пока явно не удаляется из файловой системы ,
причем перезагрузка ядра не влияет .
Этот тип избыточен , поэтому практически не применяется.
Стандарты POSIX имеют несколько редакций :
1. 1988 год - определял интерфейс между языком Си и ядром
2. 1990 - описание си-шного API
3. 1992 - описание шелл и более 100 утилит
4. 1993 - синхронизация , асинхронный ввод-вывод , семафоры , sheduling , очереди
5. 1996 - pthreads
Глава 2 : POSIX IPC
К ним относятся
1. Очереди
2. Семафоры
3. Разделяемая память
Все эти обьекты идентифицируются полными именами.
Эти обьекты создаются с помощью функций mq_open , sem_open , shm_open .
При этом происходят проверки :
1. Идентификатор пользователя должен быть равен 0 - рут
2. Проверяются права на чтение-запись
3. ID группы процесса совпадает с групповым ID обьекта IPC
4. Бит разрешения для прочих пользователей должен быть установлен
При создании обьекта IPC нужно указать набор флагов , аналогичный как и при открытии
функции open .
Глава 3 : SYSTEM V IPC
К ним относятся те же обьекты
1. Очереди
2. Семафоры
3. Разделяемая память
Идентификатор имеет тип key_t , который возвращается функцией ftok
key_t ftok(const char *path , int id);
И сервер , и клиент должны иметь одно и то же имя для идентификации .
Рассмотрим следующий пример : в качестве параметра этой программе нужно дать путь к какому-то конкретному
файлу , будет сначала для него вызвана системная функция stat ,
а потом припенена ftok (все функции с большой буквы - это врапперы для одноименных функций ):
//svipc/stok.c
int main(int argc, char **argv)
{
struct stat stat;
if (argc != 2)
err_quit("usage: ftok ");
Stat(argv[1], &stat);
printf("st_dev: %lx, st_ino: %lx, key: %x\n",
(u_long) stat.st_dev, (u_long) stat.st_ino,
Ftok(argv[1], 0x57));
exit(0);
}
Его вывод у меня был примерно таким :
st_dev: 809, st_ino: 15dfae, key: 5709dfae
Функция ftok изпользует битовое представление некоторых параметров полученной структуры stat.
Права обьекта ipc хранятся в структуре ipc_perm :
При открытии обьекта IPC выполняется следующая логическая последовательность действий :
Как правило , обьект IPC всегда создается с ключом IPC_CREAT и флаги не устанавливаются .
Обьект IPC создается с помощью одной из трех функций getXXX :
msgget , semget , shmget .
Структура ipc_perm содержит счетчик seq , в которой ядро хранит порядковый номер канала .
При удалении обьекта счетчик увеличивается.
Отличие этого счетчика от , например , дескриптора файла , в том , что каждый процесс
при открытии своих файлов каждый раз создает свои собственные дескрипторы,
которые никак не пересекаются с дескрипторами из других процессов,
а вот счетчик seq - один для всей системы .
Идентификатор IPC также един для всей системы и представляет из себя целое число .
В следующей программе выводятся идентификаторы , которые генерятся программой msgget :
//svmsg/slot.c
int main(int argc, char **argv)
{
int i, msqid;
for (i = 0; i < 10; i++) {
msqid = Msgget(IPC_PRIVATE, SVMSG_MODE | IPC_CREAT);
printf("msqid = %d\n", msqid);
Msgctl(msqid, IPC_RMID, NULL);
}
exit(0);
}
При очередном проходе цикла msgget создает очередь сообщений ,
а msgctl тут же удаляет ее .
При повторном запуске программы номера идентификаторов IPC будут уже совсем другие .
Для просмотра и удаления обьектов IPC System V существуют консольные команды
ipcs и ipcrm .
|