Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
практична робота 4.doc
Скачиваний:
2
Добавлен:
25.11.2019
Размер:
206.34 Кб
Скачать

Використовування системного виклику shmctl() для звільнення ресурсу

Для тієї ж мети – видалити область пам'яті, що розділяється, з системи – можна скористатися і системним викликом 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 ми говорили, що в багатьох сучасних операційних системах існує розширена реалізація поняття процес, коли процес є сукупністю виділених йому ресурсів і набору ниток виконання. Нитки процесу розділяють його програмний код, глобальні змінні і системні ресурси, але кожна нитка має власний програмний лічильник, свій вміст регістрів і свій стек. Оскільки глобальні змінні у ниток виконання є загальними, вони можуть використовувати їх, як елементи пам'яті, що розділяється, не вдаючись до механізму, описаного вище.

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

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

Функція pthread_self()

#include <pthread.h>

pthread_t pthread_self(void);

Опис функції

Функція pthread_self повертає ідентифікатор поточної нитки виконання.

Тип даних pthread_t є синонімом для одного з цілочисельних типів мови З.