Використання поділюваної пам’яті 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Використання поділюваної пам’яті



Процеси можуть взаємодіяти один з одним безпосередньо шля­хом поділу (спільного використання) ділянок віртуального адресного простору та обміну даними через поділювану пам’ять. Процеси ведуть читання і запис даних в області поділюваної пам’яті, використовуючи для цього ті самі машинні команди, що й при роботі зі звичайною пам’яттю.

Після створення області поділюваної пам’яті та приєднання її до віртуального адресного простору процесу ця область стає доступ­ною так само, як будь-яка ділянка віртуальної пам’яті; для доступу до даних, що перебувають у ній, не потрібні звертання до якихось до­даткових системних функцій.

Механізм поділу пам’яті має багато спільного з механізмом функціонування файлової системи. Але на відміну від файлів ядро не має відомостей про те, які процеси можуть використати механізм поді­люваної пам’яті, а, отже, воно не може автоматично очищати невико­ристовувані структури механізму взаємодії процесів, оскільки ядру не відомо, які із цих структур більше не потрібні. Таким чином, процеси, що завершилися внаслідок виникнення помилки, можуть залишити після себе непотрібні і не використовувані структури, що переванта­жують і засмічують систему. Для того, щоб уникнути подібних ситуа­цій, необхідно з великою обережністю користуватися цим механізмом і обов’язково видаляти поділювану пам’ять після використання.

 

Семафори

У наш час все більше значення надається великим обчислю­вальним системам, таким як багатопроцесорні обчислювальні комп­лекси та мережі ЕОМ. Основним засобом збільшення потужностей об­числювальних машин є підвищення в них рівня паралелізму. Оче­вид­но, що паралельність в апаратурі відбивається й на програмному забез­печенні. У зв’язку із цим значно зростає інтерес до паралельних про­цесів і проблем їхньої синхронізації.

На сьогоднішній день запропонована велика кількість різних систем синхронізації процесів. До них відносяться:

– блокування пам’яті;

– семафори;

– критичні області;

– умовні критичні області;

– монітори;

– виключаючі області тощо.

Один зі способів синхронізації паралельних процесів – сема­фори Дейкстри, реалізовані в ОС LINUX.

Синхронізація процесів

Визначимо поняття процесу як завдання, виконуваного в ос. Оскільки завдання в багатовикористовуваній системі повинні викону­ватися незалежно і можуть виконуватися паралельно, то і процеси, що їх представляють, повинні бути незалежними і паралельно викону-ваними.

Процесам для роботи часто потрібні різні пристрої та допоміж­ні програми, які можна назвати відповідно апаратними і програмними ресурсами. Якщо ми хочемо ефективно використати ці ресурси, то ті й інші повинні спільно використатися декількома процесами. Такі спіль­но використовувані ресурси називаються поділюваними ресурсами.

Якщо за умовами роботи потрібно, щоб поділювані ресурси одномоментно були доступні тільки одному процесу, то такі ресурси називаються критичними.

Під незалежністю процесів розуміється, що крім (досить рід­ких) моментів явного зв’язку, процеси розглядаються як зовсім неза­лежні один від одного. Але насправді вони не є цілком незалежними, тому що вони можуть використати в процесі свого виконання ті самі ресурси. Процес упорядкування зв’язку між конкуруючими процесами називається синхронізацією. Синхронізація задається за допомогою синхронізуючих правил. Реалізація таких правил здійснюється за допо­могою засобів синхронізації.

Елементарні прийоми синхронізації, такі як використання за­гальних змінних, мають ряд недоліків, які іноді приводять до немож­ливості одержання правильних рішень. Тому виникла необхідність у створенні спеціальних синхронізуючих примітивів.

Такі примітиви за назвою P та V -операції були запропоновані Дейкстрою в 1968 р. Ці операції можуть виконуватися тільки над спе­ціальними змінними, називаними семафорами або семафорними змін­ними. Семафори є цілими величинами та спочатку були визначені як приймаючі тільки ненегативні значення. Крім того, якщо їх викорис­тати для рішення завдань взаємного виключення, то область їх значень може бути обмежена лише 0 або 1. Однак надалі була показана важли­ва область застосування семафорів, що приймають будь-які цілі пози­тивні значення. Такі семафори одержали назву “загальних семафорів” на відміну від “двійкових семафорів”, використовуваних у завданнях взаєм­ного виключення. P та V операції є єдиними операціями, виконуваними над семафорами. Іноді вони називаються семафорними операціями.

Дамо визначення P та V- операцій у тому вигляді, у якому вони були запропоновані Дейкстрою.

V -операція (V (S)) – операція з одним аргументом, що повинен бути семафором.

Ця операція збільшує значення аргументу на 1.

P- операція (P (S)) – операція з одним аргументом, що повинен бути семафором. Її призначення – зменшити величину аргументу на 1, якщо тільки ре­зультуюче значення не стає негативним.

Завершення P -операції, тобто рішення про те, що дійсний мо­мент є підходящим для виконання зменшення і наступне зменшення значення аргументу, повинне розглядатися як неподільна операція.

Ці визначення справедливі як для загальних, так для двійкових семафорів.

Реалізація семафорів

Системні виклики для роботи із семафорами містяться в пакеті IPC (підключається файл описів – <sys/ipc.h>). Ці виклики забезпе­чують синхронізацію виконання паралельних процесів, виконуючи на­бір дій тільки над групою семафорів (засобами низького рівня).

Linux підтримує числові семафори (як розширення двійкових семафорів). Семафори Linux носять не обов’язковий, а повідомний характер. Це означає, що зв’язок між семафором і тим ресурсом (ре­сурсами), доступ до якого розмежовує семафор, є чисто логічним. Як­що при звертанні до цього ресурсу процес не запросить доступ до ньо­го через семафор, ніхто не перешкодить процесу одержати цей доступ (при наявності відповідних прав). Таким чином, процеси повинні за­здалегідь домовлятися про використання семафорів.

Кожен семафор у системі Linux являє собою набір значень (вектор семафорів). Пов’язані із семафорами системні функції є уза­гальненням операцій P та V- семафорів Дейкстри, у них допускається одночасне виконання декількох операцій (над семафорами, що на­лежать одному вектору, так звані векторні операції). Ядро виконує операції комплексно; жоден зі сторонніх процесів не зможе переуста­новлювати значення семафорів, поки всі операції не будуть виконані. Якщо ядро з якихось причин не може виконати всі операції, воно не виконує ні однієї; процес припиняє свою роботу доти, поки ця можли­вість не буде надана.

Семафор в LINUX складається з наступних елементів:

– значення семафора;

– ідентифікатор останнього із процесів, що працювали із семафором;

– кількість процесів, що очікують збільшення значення семафора;

– кількість процесів, що очікують моменту, коли значення се­мафора стане рівним 0.

Для створення набору семафорів та одержання доступу до них використається системна функція semget, для виконання різних керую­чих операцій над набором – функція semctl, для роботи зі значеннями семафорів – функція semop.

 

Системні виклики для роботи з поділюваною пам’яттю

Системні виклики для роботи з поділюваною пам’яттю в ОС Linux описані в бібліотеці <sys/shm.h>.

Функція shmget створює нову область поділюваної пам’яті або повертає адресу вже існуючої області, функція shmat логічно приєднує область до віртуального адресного простору процесу, функція shmdt від’єднує її, а функція shmctl дозволяє одержувати інформацію про стан поділюваної пам’яті та робити над нею операції.

SHMGET

Створення області поділюваної пам’яті або одержання номера дескриптора існуючої області:

int shmget(key_t key, int size, int flag);

id = shmget(key, size, flag);

де id – ідентифікатор області поділюваної пам’яті, key – номер області, size – обсяг області в байтах, flag – параметри створення і права доступу.

Ядро використає key для ведення пошуку в таблиці поділю­ваної пам’яті: якщо підходящий запис виявлений і є дозвіл на доступ, ядро повертає викликаючому процесу зазначений у записі дескриптор. Якщо запис не знайдений і користувач встановив прапор IPC_CREAT, що вказує на необхідність створення нової області, ядро перевіряє знаходження розміру області у встановлених системою межах і ви­діляє область.

Ядро записує установки прав доступу, розмір області та по­кажчик на відповідний запис таблиці областей у таблицю поділюваної пам’яті і встановлює прапор, що свідчить про те, що з областю не зв’я­зана окрема пам’ять.

Області виділяється пам’ять (таблиці сторінок і т.п.) тільки то­ді, коли процес приєднує область до свого адресного простору. Ядро встановлює також прапор, що говорить про те, що по завершенні ос­таннього пов’язаного з областю процесу область не повинна звільня­тися. Таким чином, дані в поділюваній пам’яті залишаються в цілості, навіть якщо вона не належить жодному із процесів (як частина віртуа­льного адресного простору останнього).

SHMAT

Приєднує область поділюваної пам’яті до віртуального адрес­ного простору процесу:

void *shmat(int id, void *addr, int flag);

virtaddr = shmat(id, addr, flag);

Значення id, що повертається функцією shmget, ідентифікує область поділюваної пам’яті, addr є віртуальною адресою, за якою ко­ристувач хоче підключити область, а за допомогою прапорів (flag) можна вказати, чи призначена область тільки для читання і чи пот­рібно ядру округляти значення зазначеної користувачем адреси. Зна­чення, що повертається функцією virtaddr, являє собою віртуальну ад­ресу, за якою ядро зробило підключення області і яка не завжди збі­гається з адресою, зазначеною користувачем. На початку виконання системної функції shmat ядро перевіряє наявність у процесу необхід­них прав доступу до області. Воно досліджує зазначену користувачем адресу; якщо вона дорівнює 0, ядро вибирає віртуальну адресу на свій розсуд. Область поділюваної пам’яті не повинна перетинатися у віртуальному адресному просторі процесу з іншими областями; отже, її вибір повинен проводитись розумно й обережно. Так, наприклад, процес може збільшити розмір приналежної йому області даних за до­помогою системного виклику brk, і нова область даних буде містити адреси, суміжні з колишньою областю; тому ядру не слід приєднувати область поділюваної пам’яті занадто близько до області даних про­цесу. Так само не слід розміщати область поділюваної пам’яті поблизу від вершини стека, щоб стек при своєму наступному збільшенні не за­лазив за її межі. Якщо, наприклад, стек росте в напрямку збільшення адрес, найкраще розмістити область поділюваної пам’яті безпосеред­ньо перед початком області стека. Ядро перевіряє можливість розмі­щення області поділюваної пам’яті в адресному просторі процесу й приєднує її, якщо це можливо.

Якщо викликаючий процес є першим процесом, що приєднує область, ядро виділяє для області всі необхідні таблиці, записує час приєднання у відповідне поле таблиці поділюваної пам’яті та повертає процесу віртуальну адресу, за якою область була фактично підключена.

SHMDT

Від’єднання області поділюваної пам’яті від віртуального ад­ресного простору процесу:

int shmdt(void *addr);

де addr – віртуальна адреса, повернута функцією shmat. Процес використає віртуальну адресу поділюваної пам’яті, а не її іденти­фікатор, оскільки цей ідентифікатор може бути вилучений із системи. Ядро робить пошук області за зазначеною адресою та від’єднує її від адресного простору процесу. Оскільки в таблицях областей відсутні зворотні покажчики на таблицю поділюваної пам’яті, ядру доводиться переглядати таблицю поділюваної пам’яті в пошуках запису, що вка­зує на дану область, і записувати у відповідне поле час останнього від­ключення області.

Від’єднання області від віртуального адресного простору про­цесу не означає видалення області: відомості про неї залишаються в таблиці поділюваної пам’яті, дані, що містяться в ній, також зберігаю­ться. Очищення таблиць і звільнення пам’яті можна добитись за допо­могою відповідного прапора в операції shmctl.

SHMCTL

Одержання інформації про стан області поділюваної пам’яті та установка параметрів для неї:

int shmctl(int id, int cmd, struct shmid_ds *buf);

Значення id (повертається функцією shmget) ідентифікує запис таблиці поділюваної пам’яті, cmd визначає тип операції, а buf є ад­ресою користувальницької структури, що зберігає інформацію про стан області. Типи операцій описуються списком визначень у файлі sys/ipc.h:

#define IPC_RMID 10 //видалити ідентифікатор (область)

#define IPC_SET 11 //установити параметри

#define IPC_STAT 12 //одержати параметри

За допомогою команди (прапорця) IPC_RMID можна видалити область id. Видаляючи область поділюваної пам’яті, ядро звільняє від­повідний їй запис у таблиці поділюваної пам’яті та переглядає табли­цю областей: якщо область не була приєднана до жодного із процесів, ядро звільняє запис таблиці і всі виділені області ресурси. Якщо ж об­ласть як і раніше підключена до якихось процесів (значення лічиль­ни­ка посилань на неї більше 0), ядро тільки скидає прапор, що говорить про те, що по завершенні останнього пов’язаного з нею процесу об­ласть не повинна звільнятися. Процеси, що вже використовують об­ласть поділюваної пам’яті, продовжують працювати з нею, нові ж про­цеси не можуть приєднати її. Коли всі процеси відключать область, ядро звільнить її.

 



Поделиться:


Последнее изменение этой страницы: 2016-04-26; просмотров: 216; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.141.198.146 (0.02 с.)