Использование системного вызова shmctl() для освобождения ресурса — КиберПедия 

Биохимия спиртового брожения: Основу технологии получения пива составляет спиртовое брожение, - при котором сахар превращается...

Типы сооружений для обработки осадков: Септиками называются сооружения, в которых одновременно происходят осветление сточной жидкости...

Использование системного вызова shmctl() для освобождения ресурса

2018-01-04 283
Использование системного вызова shmctl() для освобождения ресурса 0.00 из 5.00 0 оценок
Заказать работу

Для той же цели – удалить область разделяемой памяти из системы – можно воспользоваться и системным вызовом shmctl(). Этот системный вызов позволяет полностью ликвидировать область разделяемой памяти в операционной системе по заданному дескриптору средства IPC, если, конечно, у вас хватает для этого полномочий. Системный вызов shmctl() позволяет выполнять и другие действия над сегментом разделяемой памяти, но их изучение лежит за пределами нашего курса.

Системный вызов shmctl() Прототип системного вызова #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h>   int shmctl(int shmid, int cmd, struct shmid_ds *buf); Описание системного вызова Системный вызов shmctl предназначен для получения информации об области разделяемой памяти, изменения ее атрибутов и удаления из системы. Данное описание не является полным описанием системного вызова, а ограничивается рамками текущего курса. Для изучения полного описания обращайтесь к UNIX Manual. В нашем курсе мы будем пользоваться системным вызовом shmctl только для удаления области разделяемой памяти из системы. Параметр shmid является дескриптором System V IPC для сегмента разделяемой памяти, т. е. значением, которое вернул системный вызов shmget() при создании сегмента или при его поиске по ключу. В качестве параметра cmd в рамках нашего курса мы всегда будем передавать значение IPC_RMID – команду для удаления сегмента разделяемой памяти с заданным идентификатором. Параметр buf для этой команды не используется, поэтому мы всегда будем подставлять туда значение NULL. Возвращаемое значение Системный вызов возвращает значение 0 при нормальном завершении и значение -1 при возникновении ошибки.

Разделяемая память и системные вызовы fork(), exec() и функция exit()

Важным вопросом является поведение сегментов разделяемой памяти при выполнении процессом системных вызовов fork(), exec() и функции exit().

При выполнении системного вызова fork() все области разделяемой памяти, размещенные в адресном пространстве процесса, наследуются порожденным процессом.

При выполнении системных вызовов exec() и функции exit() все области разделяемой памяти, размещенные в адресном пространстве процесса, исключаются из его адресного пространства, но продолжают существовать в операционной системе.

Самостоятельное написание, компиляция и запуск программы для организации связи двух процессов через разделяемую память.

Для закрепления полученных знаний напишите две программы, осуществляющие взаимодействие через разделяемую память. Первая программа должна создавать сегмент разделяемой памяти и копировать туда собственный исходный текст, вторая программа должна брать оттуда этот текст, печатать его на экране и удалять сегмент разделяемой памяти из системы.

Понятие о нити исполнения (thread) в UNIX. Идентификатор нити исполнения. Функция pthread_self()

На лекции 4 мы говорили, что во многих современных операционных системах существует расширенная реализация понятия процесс, когда процесс представляет собой совокупность выделенных ему ресурсов и набора нитей исполнения. Нити процесса разделяют его программный код, глобальные переменные и системные ресурсы, но каждая нить имеет собственный программный счетчик, свое содержимое регистров и свой стек. Поскольку глобальные переменные у нитей исполнения являются общими, они могут использовать их, как элементы разделяемой памяти, не прибегая к механизму, описанному выше.

В различных версиях операционной системы UNIX существуют различные интерфейсы, обеспечивающие работу с нитями исполнения. Мы кратко ознакомимся с некоторыми функциями, позволяющими разделить процесс на thread 'ы и управлять их поведением, в соответствии со стандартом POSIX. Нити исполнения, удовлетворяющие стандарту POSIX, принято называть POSIX thread 'ами или, кратко, pthread'ами.

К сожалению, операционная система Linux не полностью поддерживает нити исполнения на уровне ядра системы. При создании нового thread 'а запускается новый традиционный процесс, разделяющий с родительским традиционным процессом его ресурсы, программный код и данные, расположенные вне стека, т.е. фактически действительно создается новый thread, но ядро не умеет определять, что эти thread 'ы являются составными частями одного целого. Это "знает" только специальный процесс-координатор, работающий на пользовательском уровне и стартующий при первом вызове функций, обеспечивающих POSIX интерфейс для нитей исполнения. Поэтому мы сможем наблюдать не все преимущества использования нитей исполнения (в частности, ускорить решение задачи на однопроцессорной машине с их помощью вряд ли получится), но даже в этом случае thread 'ы можно задействовать как очень удобный способ для создания процессов с общими ресурсами, программным кодом и разделяемой памятью.

Каждая нить исполнения, как и процесс, имеет в системе уникальный номер – идентификатор thread'a. Поскольку традиционный процесс в концепции нитей исполнения трактуется как процесс, содержащий единственную нить исполнения, мы можем узнать идентификатор этой нити и для любого обычного процесса. Для этого используется функция pthread_self(). Нить исполнения, создаваемую при рождении нового процесса, принято называть начальной или главной нитью исполнения этого процесса.

Функция pthread_self() Прототип функции #include <pthread.h> pthread_t pthread_self(void); Описание функции Функция pthread_self возвращает идентификатор текущей нити исполнения. Тип данных pthread_t является синонимом для одного из целочисленных типов языка C.

Создание и завершение thread'а. Функции pthread_create(), pthread_exit(), pthread_join()

Нити исполнения, как и традиционные процессы, могут порождать нити-потомки, правда, только внутри своего процесса. Каждый будущий thread внутри программы должен представлять собой функцию с прототипом

void *thread(void *arg);

Параметр arg передается этой функции при создании thread 'a и может, до некоторой степени, рассматриваться как аналог параметров функции main(), о которых мы говорили на семинарах 3–4. Возвращаемое функцией значение может интерпретироваться как аналог информации, которую родительский процесс может получить после завершения процесса-ребенка. Для создания новой нити исполнения применяется функция pthread_create().

Функция для создания нити исполнения Прототип функции #include <pthread.h> int pthread_create(pthread_t *thread, pthread_attr_t *attr, void * (*start_routine)(void *), void *arg); Описание функции Функция pthread_create служит для создания новой нити исполнения (thread'а) внутри текущего процесса. Настоящее описание не является полным описанием функции, а служит только целям данного курса. Для изучения полного описания обращайтесь к UNIX Manual. Новый thread будет выполнять функцию start_routine с прототипом void *start_routine(void *) передавая ей в качестве аргумента параметр arg. Если требуется передать более одного параметра, они собираются в структуру, и передается адрес этой структуры. Значение, возвращаемое функцией start_routine не должно указывать на динамический объект данного thread'а. Параметр attr служит для задания различных атрибутов создаваемого thread'а. Их описание выходит за рамки нашего курса, и мы всегда будем считать их заданными по умолчанию, подставляя в качестве аргумента значение NULL. Возвращаемые значения При удачном завершении функция возвращает значение 0 и помещает идентификатор новой нити исполнения по адресу, на который указывает параметр thread. В случае ошибки возвращается положительное значение (а не отрицательное, как в большинстве системных вызовов и функций!), которое определяет код ошибки, описанный в файле <errno.h>. Значение системной переменной errno при этом не устанавливается.

Мы не будем рассматривать ее в полном объеме, так как детальное изучение программирования с использованием thread 'ов не является целью данного курса.

Важным отличием этой функции от большинства других системных вызовов и функций является то, что в случае неудачного завершения она возвращает не отрицательное, а положительное значение, которое определяет код ошибки, описанный в файле <errno.h>. Значение системной переменной errno при этом не устанавливается. Результатом выполнения этой функции является появление в системе новой нити исполнения, которая будет выполнять функцию, ассоциированную со thread 'ом, передав ей специфицированный параметр, параллельно с уже существовавшими нитями исполнения процесса.

Созданный thread может завершить свою деятельность тремя способами:

· С помощью выполнения функции pthread_exit(). Функция никогда не возвращается в вызвавшую ее нить исполнения. Объект, на который указывает параметр этой функции, может быть изучен в другой нити исполнения, например, в породившей завершившийся thread. Этот параметр, следовательно, должен указывать на объект, не являющийся локальным для завершившегося thread'а, например, на статическую переменную;

· С помощью возврата из функции, ассоциированной с нитью исполнения. Объект, на который указывает адрес, возвращаемый функцией, как и в предыдущем случае, может быть изучен в другой нити исполнения, например, в породившей завершившийся thread, и должен указывать на объект, не являющийся локальным для завершившегося thread'а;

· Если в процессе выполняется возврат из функции main() или где-либо в процессе (в любой нити исполнения) осуществляется вызов функции exit(), это приводит к завершению всех thread'ов процесса.

Функция для завершения нити исполнения Прототип функции #include <pthread.h> void pthread_exit(void *status); Описание функции Функция pthread_exit служит для завершения нити исполнения (thread) текущего процесса. Функция никогда не возвращается в вызвавший ее thread. Объект, на который указывает параметр status, может быть впоследствии изучен в другой нити исполнения, например в нити, породившей завершившуюся нить. Поэтому он не должен указывать на динамический объект завершившегося thread'а.

Одним из вариантов получения адреса, возвращаемого завершившимся thread'ом, с одновременным ожиданием его завершения является использование функции pthread_join(). Нить исполнения, вызвавшая эту функцию, переходит в состояние ожидание до завершения заданного thread 'а. Функция позволяет также получить указатель, который вернул завершившийся thread в операционную систему.

Функция pthread_join() Прототип функции #include <pthread.h> int pthread_join (pthread_t thread, void **status_addr); Описание функции Функция pthread_join блокирует работу вызвавшей ее нити исполнения до завершения thread'а с идентификатором thread. После разблокирования в указатель, расположенный по адресу status_addr, заносится адрес, который вернул завершившийся thread либо при выходе из ассоциированной с ним функции, либо при выполнении функции pthread_exit(). Если нас не интересует, что вернула нам нить исполнения, в качестве этого параметра можно использовать значение NULL. Возвращаемые значения Функция возвращает значение 0 при успешном завершении. В случае ошибки возвращается положительное значение (а не отрицательное, как в большинстве системных вызовов и функций!), которое определяет код ошибки, описанный в файле <errno.h>. Значение системной переменной errno при этом не устанавливается.

Поделиться с друзьями:

Типы оградительных сооружений в морском порту: По расположению оградительных сооружений в плане различают волноломы, обе оконечности...

Своеобразие русской архитектуры: Основной материал – дерево – быстрота постройки, но недолговечность и необходимость деления...

Архитектура электронного правительства: Единая архитектура – это методологический подход при создании системы управления государства, который строится...

История создания датчика движения: Первый прибор для обнаружения движения был изобретен немецким физиком Генрихом Герцем...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.012 с.