- Главная
- Информатика
- Синхронизация обмена данными
Содержание
- 2. Синхронизация обмена данными Для корректного обмена данными необходима в случае, когда два и более выполняющихся процесса
- 3. Когда поток изменяет значение переменной, существует потенциальная опасность, что другой поток может прочитать еще не до
- 6. Объекты синхронизации Семафоры (semaphore) Мьютексы (Mutaual Exception) Взаимные блокировки (spinlock) Блокировки чтения-записи Условные переменные Атомарные операции
- 7. Семафоры Механизм семафоров, реализованный в ОС UNIX, является обобщением классического механизма семафоров общего вида, предложенного Дейкстрой.
- 8. Для работы с семафорами поддерживаются три системных вызова: semget для создания и получения доступа к набору
- 9. Создание семафора int semget(key_t key, int count, int flag); прямые параметры key и flag и возвращаемое
- 10. Управление состоянием семафора oldval = semop(int semid, struct sembuf *oplist, size_t count); где id - это
- 11. Если проверка прав доступа проходит нормально, и указанные в массиве oplist номера семафоров не выходят за
- 12. Основным поводом для введения массовых операций над семафорами было стремление дать программистам возможность избегать тупиковых ситуаций
- 13. Управление объектами семафоров int semctl(int semid, int number, int cmd, arg); Функция semctl позволяет выполнять операции,
- 14. Аргумент cmd может принимать следующие значения: IPC_STAT Скопируйте информацию из структуры данных набора семафоров в структуру,
- 15. Мьютексы Мьютексы можно рассматривать как двоичные семафоры. блокировка, которая устанавливается (запирается) перед обращением к разделяемому ресурсу
- 16. Переменные-мьютексы определяются с типом pthread_mutex_t. Прежде чем использовать переменную мьютекс, мы должны сначала инициализировать ее, записав
- 17. Системные вызовы pthread_mutex_init и int pthread_mutex_destroy #include int pthread_mutex_init( pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
- 19. Скачать презентацию
Синхронизация обмена данными
Для корректного обмена данными необходима в случае, когда два
Синхронизация обмена данными
Для корректного обмена данными необходима в случае, когда два
Обычно для этого используются исключающие блокировки – механизмы, при которых в один момент времени доступ к ресурсу для записи и чтения имеет только один процесс, а остальные находятся в состоянии ожидания.
Когда поток изменяет значение переменной, существует потенциальная опасность, что другой поток
Когда поток изменяет значение переменной, существует потенциальная опасность, что другой поток
Объекты синхронизации
Семафоры (semaphore)
Мьютексы (Mutaual Exception)
Взаимные блокировки (spinlock)
Блокировки чтения-записи
Условные переменные
Атомарные операции
Сериальные блокировки
Переменные,
Объекты синхронизации
Семафоры (semaphore)
Мьютексы (Mutaual Exception)
Взаимные блокировки (spinlock)
Блокировки чтения-записи
Условные переменные
Атомарные операции
Сериальные блокировки
Переменные,
Семафоры для чтения/записи
Мьютексы реального времени
Механизмы ожидания завершения
Семафоры
Механизм семафоров, реализованный в ОС UNIX, является обобщением классического механизма семафоров
Семафоры
Механизм семафоров, реализованный в ОС UNIX, является обобщением классического механизма семафоров
Семафор в ОС UNIX состоит из следующих элементов:
значение семафора;
идентификатор процесса, который хронологически последним работал с семафором;
число процессов, ожидающих увеличения значения семафора;
число процессов, ожидающих нулевого значения семафора.
Для работы с семафорами поддерживаются три системных вызова:
semget для создания
Для работы с семафорами поддерживаются три системных вызова:
semget для создания
semop для манипулирования значениями семафоров (это именно тот системный вызов, который позволяет процессам синхронизоваться на основе использования семафоров);
semctl для выполнения разнообразных управляющих операций над набором семафоров.
Создание семафора
int semget(key_t key, int count, int flag);
прямые параметры key и
Создание семафора
int semget(key_t key, int count, int flag);
прямые параметры key и
Управление состоянием семафора
oldval = semop(int semid, struct sembuf *oplist, size_t count);
где
Управление состоянием семафора
oldval = semop(int semid, struct sembuf *oplist, size_t count);
где
struct sembuf {
u_short sem_num; /* semaphore # */
short sem_op; /* semaphore operation */ short sem_flg; /* operation flags */
};
Если проверка прав доступа проходит нормально, и указанные в массиве oplist
Если проверка прав доступа проходит нормально, и указанные в массиве oplist
Если значение поля операции положительно, то значение семафора увеличивается на значение поля sem_op, а все процессы, ожидающие увеличения значения семафора, активизируются (пробуждаются в терминологии UNIX).
Если значение поля операции равно нулю, то если значение семафора также равно нулю, выбирается следующий элемент массива oplist. Если же значение семафора отлично от нуля, то ядро увеличивает на единицу число процессов, ожидающих нулевого значения семафора, а обратившийся процесс переводится в состояние ожидания (усыпляется в терминологии UNIX).
Если значение поля операции отрицательно, и его абсолютное значение меньше или равно значению семафора, то ядро прибавляет это отрицательное значение к значению семафора. Если в результате значение семафора стало нулевым, то ядро активизирует (пробуждает) все процессы, ожидающие нулевого значения этого семафора. Если же значение семафора меньше абсолютной величины поля операции, то ядро увеличивает на единицу число процессов, ожидающих увеличения значения семафора и откладывает (усыпляет) текущий процесс до наступления этого события.
Основным поводом для введения массовых операций над семафорами было стремление дать
Cреди флагов-параметров системного вызова semop может содержаться флаг с символическим именем IPC_NOWAIT, наличие которого заставляет ядро ОС UNIX не блокировать текущий процесс, а лишь сообщать в ответных параметрах о возникновении ситуации, приведшей бы к блокированию процесса при отсутствии флага IPC_NOWAIT.
Управление объектами семафоров
int semctl(int semid, int number, int cmd, arg);
Функция semctl
Управление объектами семафоров
int semctl(int semid, int number, int cmd, arg);
Функция semctl
union semun {
int val; /* value for SETVAL */
struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* array for GETALL, SETALL */
/* Linux specific part: */
struct seminfo *__buf; /* buffer for IPC_INFO */
};
Аргумент cmd может принимать следующие значения:
IPC_STAT Скопируйте информацию из структуры данных
Аргумент cmd может принимать следующие значения:
IPC_STAT Скопируйте информацию из структуры данных
IPC_SET Внесите значения некоторых членов структуры semid_ds, на которую указывает arg.buf , в структуру данных набора семафоров и обновите sem_ctime. Присвоить следующим полям структуры данных struct semid_ds соответствующие значения, на которые указывает arg.buf sem_perm.uid sem_perm.gid sem_perm.mode /* Только младшие 9 битов */ Эта команда может выполняться только процессом, который имеет действующий идентификатор пользователя, равный либо идентификатору суперпользователя, либо создателя или владельца набора семафоров. Аргумент semnum игнорируется.
IPC_RMID Немедленно удалить из системы набор семафоров и структуры его данных, запускающие все процессы, находящиеся в режиме ожидания (при этом возвращается сообщение об ошибке, а errno присваивается значение EIDRM). Эта команда может выполняться только процессом, который имеет действующий идентификатор пользователя, равный либо идентификатору суперпользователя, либо создателя или владельца набора семафоров. Аргумент semnum игнорируется.
GETALL Возвращает значение semval всем семафорам в массиве arg.array. Аргумент semnum игнорируется. Для этого вызывающему процессу нужны права на чтение.
GETNCNT Системный вызов возвращает значение semncnt семафору semnum-th (например, число процессов, ожидающих увеличения значения semval семафора semnum-th). Для этого вызывающему процессу нужны права на чтение.
GETPID Системный вызов возвращает значение sempid семафору semnum-th (например, идентификатор процесса, который последним делал вызов semop семафору semnum-th). Для этого вызывающему процессу нужны права на чтение.
GETVAL системный вызов возвращает значение semval семафору semnum-th. Для этого вызывающему процессу нужны права на чтение.
GETZCNT Системный вызов возвращает значение semzcnt семафору semnum-th (например, количество процессов, ожидающих, чтобы значение semval семафора semnum-th стало равным нулю). Для этого вызывающему процессу нужны права на чтение.
SETALL Установить значение semval всех семафоров равным значениям элементов массива, на который указывает arg.array, изменяя также sem_ctime, являющееся членом структуры semid_ds ; а эта структура ассоциируется с набором семафоров. История отменяемых операций удаляется для всех измененных семафоров во всех процессах. Процессы, находящиеся в очереди, активизируются, если semval становится равным нулю или значение его увеличивается. Аргумент semnum игнорируется. Для этого вызывающему процессу нужны права на чтение.
SETVAL Установите значение semval на указанное в arg.val для всех семафоров semnum-th, изменяя также sem_ctime в структуре semid_ds, соотносимой с набором семафоров. История отмененных операций удаляется для всех измененных семафоров во всех процессах. Процессы, находящиеся в очереди, активизируются, если semval становится равным нулю или значение его увеличивается. Вызывающему процессу потребуется право на его изменение.
Мьютексы
Мьютексы можно рассматривать как двоичные семафоры.
блокировка, которая устанавливается (запирается) перед обращением
Мьютексы
Мьютексы можно рассматривать как двоичные семафоры.
блокировка, которая устанавливается (запирается) перед обращением
Если в момент, когда отпирается мьютекс, заблокированными окажутся несколько потоков, все они будут запущены и первый из них, который успеет запереть мьютекс, продолжит работу. Все остальные потоки обнаружат, что мьютекс по-прежнему заперт, и опять перейдут в режим ожидания. Таким образом, доступ к ресурсу сможет получить одновременно только один поток.
Такой механизм взаимоисключений будет корректно работать только при условии, что все потоки приложения будут соблюдать одни и те же правила доступа к данным. Операционная система никак не упорядочивает доступ к данным. Если мы позволим одному потоку производить действия с разделяемыми данными, предварительно не ограничив доступ к ним, то остальные потоки могут обнаружить эти данные в противоречивом состоянии, даже если перед обращением к ним будут устанавливать блокировку.
Переменные-мьютексы определяются с типом pthread_mutex_t. Прежде чем использовать переменную мьютекс, мы
Переменные-мьютексы определяются с типом pthread_mutex_t. Прежде чем использовать переменную мьютекс, мы
Системные вызовы работы с mutex
pthread_mutex_init
pthread_mutex_destroy
pthread_mutex_lock
pthread_mutex_trylock
pthread_mutex_unlock
Системные вызовы
pthread_mutex_init и int pthread_mutex_destroy
#include
int pthread_mutex_init(
pthread_mutex_t *restrict mutex,
Системные вызовы
pthread_mutex_init и int pthread_mutex_destroy
#include
int pthread_mutex_init(
pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t *restrict attr);
Инциализирует мьютекс переданный параметром mutex. Для того, чтобы использовать параметры по умолчанию необходимо вместо attr передать NULL.
int pthread_mutex_destroy(pthread_mutex_t *restrict mutex);
Уничтожает mutex.