
- •Семинары 6-7. Средства System V ipc. Организация работы с разделяемой памятью в unix. Понятие нитей исполнения (thread'ов).
- •Программа семинара
- •Цели занятия
- •Практические работы
- •План занятия
- •Преимущества и недостатки потокового обмена данными.
- •Понятие о System V ipc.
- •Пространство имен. Адресация в System V ipc. Функция ftok().
- •Дескрипторы System V ipc.
- •Разделяемая память в unix. Системные вызовы shmget(), shmat(), shmdt().
- •Прогон программ с использованием разделяемой памяти.
- •Команды ipc и ipcrm.
- •Использование системного вызова shmctl() для освобождения ресурса.
- •Разделяемая память и системные вызовы fork(), exec() и функция exit().
- •Самостоятельное написание, компиляция и запуск программы для организации связи двух процессов через разделяемую память.
- •Понятие о нити исполнения (thread) в unix. Идентификатор нити исполнения. Функция pthread_self().
- •Создание и завершение thread'а. Функции pthread_create(), pthread_exit(), pthread_join().
- •Необходимость синхронизации процессов и нитей исполнения, использующих общую память.
Необходимость синхронизации процессов и нитей исполнения, использующих общую память.
В се рассмотренные на этом семинаре примеры являются не совсем корректными. В большинстве случаев они работают правильно, однако возможны ситуации, когда совместная деятельность этих процессов или нитей исполнения приводит к неверным и неожиданным результатом. Это связано с тем, что любые неатомарные операции, связанные с изменением содержимого разделяемой памяти, представляют собой критическую секцию процесса или нити исполнения. Вернемся к рассмотрению программ /ftp/pub/sem6-7/stud/06-1a.c и /ftp/pub/sem6-7/stud/06-1b.c. При одновременном существовании 2-х процессов в операционной системе может возникнуть следующая последовательность выполнения операций во времени:
... Процесс 1: array[0] += 1; Процесс 2: array[1] += 1; Процесс 1: array[2] += 1; Процесс 1: printf("Program 1 was spawn %d times, program 2 - %d times, total - %d times\n", array[0], array[1], array[2]); ...
Тогда печать будет давать неправильные результаты. Естественно, что воспроизвести подобную последовательность действий практически нереально. Мы не сможем подобрать необходимые времена старта процессов и степень загруженности вычислительной системы. Но мы можем смоделировать эту ситуацию, добавив в обеих программах достаточно длительные пустые циклы перед оператором array[2] += 1; Это проделано в программах /ftp/pub/sem6-7/stud/06-3a.c и /ftp/pub/sem6-7/stud/06-3b.c. Откомпилируем их, запустим любую из них один раз для создания и инициализации разделяемой памяти. Затем запустим другую и, пока она находится в цикле, запустим, например, с другого виртуального терминала, снова первую. Мы получим неожиданный результат. К ак видим, для написания корректно работающих программ необходимо обеспечивать взаимоисключение при работе с разделяемой памятью и, может быть, взаимную очередность доступа к ней. Это можно сделать с помощью рассмотренных на лекции алгоритмов синхронизации, например, алгоритма Петерсона или алгоритма булочной. Задача повышенной сложности: модифицируйте программы /ftp/pub/sem6-7/stud/06-3a.c и /ftp/pub/sem6-7/stud/06-3b.c для корректной работы с помощью алгоритма Петерсона. На следующем семинаре мы рассмотрим семафоры, которые являются средством System V IPC, предназначенным для синхронизации процессов.