QNX/UNIX: Анатомия параллелизма
QNX/UNIX: Анатомия параллелизма читать книгу онлайн
Книга адресована программистам, работающим в самых разнообразных ОС UNIX. Авторы предлагают шире взглянуть на возможности параллельной организации вычислительного процесса в традиционном программировании. Особый акцент делается на потоках (threads), а именно на тех возможностях и сложностях, которые были привнесены в технику параллельных вычислений этой относительно новой парадигмой программирования. На примерах реальных кодов показываются приемы и преимущества параллельной организации вычислительного процесса. Некоторые из результатов испытаний тестовых примеров будут большим сюрпризом даже для самых бывалых программистов. Тем не менее излагаемые техники вполне доступны и начинающим программистам: для изучения материала требуется базовое знание языка программирования C/C++ и некоторое понимание «устройства» современных многозадачных ОС UNIX.
В качестве «испытательной площадки» для тестовых фрагментов выбрана ОСРВ QNX, что позволило с единой точки зрения взглянуть как на специфические механизмы микроядерной архитектуры QNX, так и на универсальные механизмы POSIX. В этом качестве книга может быть интересна и тем, кто не использует (и не планирует никогда использовать) ОС QNX: программистам в Linux, FreeBSD, NetBSD, Solaris и других традиционных ОС UNIX.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
evaluation time 0.989699 sec.
# nice -n-19 sy11 500 .02
evaluation time 0.98391 sec.
# nice -n-19 sy12 500 .02
evaluation time 0.0863443 sec.
Выигрыш становится более чем 10-кратным.
Показанные примеры ( sy10.cc, sy11.cc, sy12.cc) в высшей степени условны: картина происходящего будет существенно другой при замене пассивного ожидания (
delay()
Спинлок
Спинлок, или «крутящаяся» блокировка, предназначен исключительно для применения в системах SMP (Symmetrical Multi-Processing), то есть в многопроцессорных системах. Поведение спинлока практически идентично классическому мьютексу, за единственным исключением — ожидающий поток не блокируется и не вытесняется. Не забывайте, речь идет о многопроцессорной системе! Основным назначением спинлока является задержка выполнения обработчиков прерываний, и предназначены они для исключения временных потерь, связанных с переключением контекстов.
Функции работы с «крутящейся» блокировкой объявлены в заголовочном файле
<рthread.h>
Операции со спинлоком
Инициализация и разрушение спинлока
int pthread_spin_init(pthread_spinlock_t* spinner, int pshared);
Функция инициализирует объект синхронизации спинлока блокировки, на который указывает аргумент
spinner
pshared
•
PTHREAD_PROCESS_SHARED
•
PTHREAD_PROCESS_PRIVATE
В случае успешного завершения функция возвращает нулевое значение, в противном случае — один из следующих кодов ошибок:
AGAIN
EBUSY
spinner
EINVAL
spinner
ENOMEM
int pthread_spin_destroy(pthread_spinlock_t* spinner);
Функция деинициализирует объект крутящейся блокировки. После деинициализации для последующего применения объекта он должен быть вновь инициализирован. Обратите внимание, результат функции не определен, если поток в данный момент крутится на блокировке, на которую указывает
spinner
spinner
Возвращаемые значения:
EOK
EBUSY
EINVAL
spinner
Захват и освобождение спинлока
int pthread_spin_lock(pthread_spinlock_t* spinner);
int pthread_spin_trylock(pthread_spinlock_t* spinner);
Это функции захвата и попытки захвата крутящейся блокировки соответственно. Как и для мьютекса, если объект
spinner
spinner
Попытка повторного захвата крутящейся блокировки из того же потока приводит к мертвой блокировке.
Функции возвращают следующие параметры:
EOK
EAGAIN
spinner
EDEADLK
spinner
EINVAL
spinner
pthread_spinlock_t
EBUSY
pthread_spin_trylock()
int pthread_spin_unlock(pthread_spinlock_t* spinner);
Вызов этой функции освобождает объект крутящейся блокировки, на который указывает аргумент
spinner
Функция может возвращать значения:
EOK
EINVAL
spinner
EPERM
5. Специфические механизмы QNX
Операционная система QNX изнутри вся построена на клиент-серверных принципах, которые вытекают из микроядерной архитектуры и обмена сообщениями микроядра. Мы не могли обойти вниманием эти механизмы, поскольку они предоставляют огромный арсенал возможностей, однако их обстоятельное описание потребовало бы отдельной книги (полное описание см. в технической документации QNX по системной архитектуре). Более того, лучшая книга по обмену сообщениями микроядра уже, пожалуй, написана и переведена на русский язык [1]. В дополнение ко всему приложение «Организация обмена сообщениями», написанное В. Зайцевым и ранее не публиковавшееся, содержит обстоятельный анализ этого механизма.
Поэтому в главе мы лишь кратко рассмотрим вопросы параллелизма и синхронизации, присущие самой микроядерной архитектуре системы.
Обмен сообщениями микроядра
Модель обмена сообщениями — это тот фундамент, на котором стоит архитектура любой микроядерной ОС, как на трех китах: SEND — RECEIVE — REPLY. Обмен сообщениями микроядра построен на трех группах вызовов native API QNX (рис. 5.1):
1. Принять сообщение. Процесс [38], являющийся сервером некоторой услуги, выполняет вызов группы
MsgReceive*()