69291

Завдання підсистеми введення-виведення ядра

Лекция

Информатика, кибернетика и программирование

Планування введення-виведення звичайно реалізоване як середньотермінове планування. Як відомо, з кожним пристроєм пов’язують чергу очікування, під час виконання блокувального виклику (такого як read() або fcntl()) потік поміщають у чергу для відповідного пристрою...

Украинкский

2014-10-02

77 KB

1 чел.

Лекція № 18

Тема: Завдання підсистеми введення-виведення ядра

План

  1.  Планування операцій введення-виведення
  2.  Буферизація
  3.  Введення-виведення із розподілом та об'єднанням
  4.  Спулінг
  5.  Обробка помилок

У цьому розділі йтиметься про деякі можливості, які надає підсистема введення-виведення ядра, та їхнє місце в загальній інфраструктурі введення-виведення.

Планування операцій введення-виведення

Планування введення-виведення звичайно реалізоване як середньотермінове планування. Як відомо, з кожним пристроєм пов'язують чергу очікування, під час виконання блокувального виклику (такого як read() або fcntl()) потік поміщають у чергу для відповідного пристрою, з якої його звичайно вивільняє оброблювач переривання, як це було описано в розділі 15.3.2. Різним пристроям можуть присвоювати різні пріоритети. Ще одним прикладом планування введення-виведення є дискове планування, розглянуте в розділі 12.

Буферизація

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

Необхідність реалізації буферизації

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

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

Різниця в обсязі даних, переданих пристроями або рівнями підсистеми введення-виведення за одну операцію. Типовим прикладом у цьому разі є мережний обмін даними, коли відправник розбиває велике повідомлення на фрагменти, а одержувач у міру отримання поміщає ці фрагменти в буфер (його ще називають буфером повторного збирання reassembly buffer) для того щоб зібрати з них первісне повідомлення. Такий буфер ще більш необхідний, оскільки фрагменти можуть приходити не в порядку відсилання.

Необхідність підтримки для застосування семантики копіювання (copy semantics). Вона полягає в тому, що інформація, записана на диск процесом, має зберігатися в тому вигляді, у якому вона перебувала у пам'яті в момент записування, незалежно від змін, зроблених після цього.

Способи реалізації буферизації

Розглянемо різні способи реалізації буферизації (рис. 15.2).

Буфер, у який копіюються дані від пристрою, можна організувати в адресному просторі процесу користувача. Хоча такий підхід і дає виграш у продуктивності, його не можна вважати прийнятним, оскільки сторінка із таким буфером може у будь-який момент бути заміщена у пам'яті та скинута на диск. Можна дозволити процесам фіксувати свої сторінки у пам'яті під час кожної операції введення-виведення, але це призводить до невиправданих витрат основної пам'яті.

Першим підходом, який реально використовують на практиці, є одинарна буферизація в ядрі. У цьому разі у ядрі створюють буфер, куди копіюють дані в міру їхнього надходження від пристрою. Коли цей буфер заповнюється, весь його вміст за одну операцію копіюють у буфер, що перебуває у просторі користувача. Аналогічно під час виведення даних їх спочатку копіюють у буфер ядра, після чого вже ядро відповідатиме за їхнє виведення на пристрій. Це дає змогу реалізувати семантику копіювання, оскільки після копіювання даних у буфер ядра інформація із буфера користувача у підсистему введення-виведення гарантовано більше не потрапить — процес може продовжувати свою роботу і використовувати цей буфер для своїх потреб.

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

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

Подвійна буферизація дає змогу відокремити виробника даних від їхнього споживача подібно до того, як це робилося для розв'язання задачі виробників-споживачів у розділах 5 і 6.

Буферизація і кешування

Буферизацію варто відрізняти від кешування. Основна відмінність між ними полягає в тому, що буфер може містити єдину наявну копію даних, тоді як кеш за визначенням зберігає у більш швидкій пам'яті копію даних з іншого місця.

З іншого боку, ділянку пам'яті в деяких випадках можна використати і як буфер, і як кеш. Наприклад, якщо після виконання операції введення із використанням буфера надійде запит на таку саму операцію, дані можуть бути отримані із буфера, який при цьому буде частиною кеша. Сукупність таких буферів називають буферним кешем (buffer cache).

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

Введення-виведення із розподілом та об'єднанням

Цікавим підходом до оптимізації операцій введення-виведення, пов'язаним із записуванням великих обсягів даних протягом однієї операції, є введення-виведення з розподілом та об'єднанням (scatter-gather I/O). У даному випадку в системі дозволяється використовувати під час введення-виведення набір непов'язаних ділянок пам'яті. При цьому можливі дві дії:

♦  дані із пристрою відсилають у набір ділянок пам'яті за одну операцію введення (операція розподілу під час введення, scatter);

♦  усі дані набору ділянок пам'яті відсилають пристрою для виведення за одну операцію (операція об'єднання під час виведення, gather).

Виконання цих дій дає змогу обійтися без додаткових операцій доступу до пристрою, які потрібно було б виконувати, коли всі ділянки пам'яті були використані для введення-виведення по одній.

В UNIX-системах (відповідно до стандарту POSIX) введення із розподілом реалізують системним викликом readv(), виведення з об'єднанням — writev().

#include <sys/uio.h>

ssize_t readvCint fdl. const struct iovec *iov. int count);

ssize_t writevfint fdl, const struct iovec *iov. int count);

де: fdl — дескриптор відкритого файла;

і ov - масив структур, які задають набір ділянок пам'яті для введення і виведення;

count — кількість структур у масиві і о v.

Кожний елемент масиву містить два поля: iovjbase, що задає адресу ділянки пам'яті, та і ov_l en, що задає її довжину. Елемент масиву має бути повністю оброблений (наприклад, заповнений до довжини iovjen за виконання readv()) перед тим як система перейде до обробки наступного.

Виклик readv() повертає загальну кількість зчитаних байтів, а виклик wri tev() — записаних.

int bytes_read;

char buf0[1024]. bufl[512];

struct iovec iov[2];

iov[0].iov_base = bufO;

iov[l].iov_base = bufl;

і ov[0J. iovjen = sizeof(bufl):

iov[l].iovjen = sizeof(buf2);

// infile. outfile - дескриптори відкритих файлів

do {

// читання у два буфери

bytes_read - readv(infile, iov, 2);

// записування із двох буферів

if (bytes_read > 0) wn'tev(outfile, iov, 2); } while (bytes_read > 0);

Win32 API надає для введення із розподілом функцію ReadFi 1 eScatter(), а для виведення з об'єднанням - WriteFileGatherO.

Спулінг

Спулінг (spooling) — технологія виведення даних із використанням буфера, що працює за принципом FIFO. Такий буфер називають агулом (spool) або ділянкою спула (spool area).

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

Роботи надходять у спул і в ньому вишиковуються у FIFO-чергу (нові роботи додаються у її хвіст). Як тільки пристрій вивільняється, роботу із голови черги передають пристрою для виведення. Звичайно спулінг пов'язаний із повільними пристроями, тому найчастіше ділянку спула організовують на жорсткому диску, а роботи відображають файлами. Для керування спулом (підтримки черги, пересилання робіт на пристрій) зазвичай використовують фоновий процес або потік ядра. Має бути доступний інтерфейс керування спулом, за допомогою якого можна переглядати вміст черги, вилучати роботи з неї, міняти їхній порядок, тимчасово призупиняти виведення (наприклад, на час обслуговування пристрою).

Зазначимо, що загалом спулінг не можна назвати технологією керування введенням-виведенням режиму ядра — його часто реалізують процеси користувача (такі як демон друкування Ірг для UNIX).

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

Обробка помилок

У підсистемі введення-виведення під час роботи виникають різні помилки, які можна віднести до кількох категорій.

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

2)  Помилки, викликані апаратними проблемами. Серед них розрізняють:

викликані тимчасовими причинами (високе навантаження на мережу, сигнал «зайнято» для модему); для цих помилок звичайною реакцією є повторна спроба виконання введення-виведення;

що вимагають втручання користувача (відсутність дискети в дисководі, відсутність паперу у принтері); за такої помилки зазвичай потрібно попросити користувача виконати певні дії;

+  викликані некоректною роботою апаратного забезпечення (збій контролера, дефектні сектори на диску); у цьому разі важливим є надання користувачу (який може виявитися представником служби технічної підтримки фірми-розробника пристрою) якомога більше повної інформації про помилку (зазначимо, що після деяких таких помилок продовження роботи системи може стати неможливим). У програмному забезпеченні передача докладних відомостей про помилку є головним завданням підсистеми введення-виведення у разі виникнення проблеми. Справді, для більшості системних викликів інтерфейс повідомлень про помилки доволі скромний (цілочисловий код повернення, глобальна змінна errno), тому  розробникам драйверів необхідно передбачати додаткові способи отримання інформації про помилку.

Питання для самоконтролю:

  1.  Планування операцій введення-виведення
  2.  Буферизація
  3.  Причини, які викликають необхідність буферизації
  4.  Буферизація і кешування
  5.  Введення-виведення із розподілом та об'єднанням
  6.  Спулінг
  7.  Обробка помилок, їх категорії


 

А также другие работы, которые могут Вас заинтересовать

73556. Введение в высокотемпературную теплотехнологию и энергетику теплотехнологии 32.17 MB
  Возобновляемые источники энергии – энергия солнца ветра тепла земли естественного движения водных потоков а также энергия существующих в природе градиентов температур. Возобновляемые ТЭР основаны на использовании возобновляемых источников энергии: солнечного излучения энергии морей рек и океанов внутреннего тепла Земли воды и воздуха энергии естественного движения водных потоков и существующих...
73557. Методи розрахунку однофазних лінійних електричних кіл синусоїдного змінного струму при наявності двох і більше джерел живлення 668.5 KB
  Застосування символічного методу при розрахунку Іф кіл СЗС при наявності двох і більше джерел живлення. Методи вузлових і контурних рівнянь та контурних струмів. Методи вузлових потенціалів (двох вузлів) та суперпозиції. Метод еквівалентного генератора.
73558. Українська історіографія на початку національного відродження (кінець XVIII — перша половина XIX ст.) 97 KB
  Україна переживала з кінця XVIII століття складний етап своєї історії. Після поділу Польщі українські землі опинилися у складі двох імперій: Російської (80% території) і Австрійської. Суспільне життя краю характеризувалося кризою кріпосницького ладу, розгортанням російського визвольногопольського національно-визвольного та процесом українського національного відродження.
73559. Источники энергии высокотемпературных теплотехнологических установок 261 KB
  Классификация реакторов высокотемпературной теплотехнологической установки; Структурная схема теплотехнологического реактора; Схемы размещения источников энергии и движения дымовых газов в камерах (зонах) реакторов высокотемпературных технологических установок; Схема тепломассообмена в рабочем пространстве высокотемпературных теплотехнических установках;
73560. Розрахунок лінійних електричних кіл синусоїдного змінного струму методом провідностей 404.5 KB
  Визначення співвідношень опорів для перетворення схеми з послідовним зєднанням опорів в схему з їх паралельним зєднанням. Визначення співвідношень провідностей для перетворення схеми з паралельним зєднанням опорів в схему з їх послідовним зєднанням...
73561. Українська iсторiографiя другої половини ХIХ – початку ХХ століть 201 KB
  Народницький напрям в українськiй iсторiографiї сформувався в 40-вi роки ХIХ столiття. Вiн став домiнуючим у другiй половинi ХIХ ст. i поширився на першi десятилiття ХХ столiття. Його засновниками були Михайло Олександрович Максимович i Микола Iванович Костомаров, а, за висловом М.С.Грушевського, він сам був «останнiм могiканом» української народницької iсторiографii.
73562. Резонансні режими в лінійних електричних колах СЗС 757.5 KB
  Резонансом напруг Іф. ЛЕК СЗС називається такий режим роботи нерозгалуженого кола, що містить послідовно з’єднані активний, індуктивний і ємнісні опори, при якому повний опір кола набуває активного характеру, спади напруг на індуктивних і ємнісних опорах компенсують один одного, а повна напруга співпадає за фазою зі струмом.
73563. М.С. ГРУШЕВСЬКИЙ В УКРАЇНСЬКІЙ ІСТОРІОГРАФІЇ 101.5 KB
  Життя і науково-організаційна діяльність. Історіософія М. С. Грушевського. Історіографічна спадщина. «Історія України-Руси». Історичні школи М.С. Грушевського та їх значення.
73564. Кола синусоїдного змінного струму з взаємною індуктивністю 688 KB
  Магнітне поле – це невідємна складова частина електромагнітного поля, що виникає при русі електричних зарядів в просторі або в провідниках у вигляді електричного струму (постійного чи змінного), а також у вигляді молекулярних струмів в постійних магнітах.