69762

Введення-виведення у режимі користувача

Лекция

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

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

Украинкский

2014-10-09

63 KB

0 чел.

Тема 10. Введення-виведення у режимі користувача

Тут зупинимося на взаємодії підсистеми введення-виведення із процесами режиму користувача та на різних методах організації введення-виведення з режиму користувача.

10.1. Синхронне введення-виведення

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

Однак синхронне введення-виведення підходить не для всіх застосувань. Зокрема, воно не підходить для таких категорій програм:

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

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

мультимедійних застосувань (відіславши запит на читання одного кадру, потрібно одночасно показувати інші).

Для вирішення цієї проблеми запропоновано кілька підходів, про які йтиметься нижче.

10.2. Багатопотокова організація введення-виведення

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

Такий підхід має багато переваг і може бути рекомендований для використання у багатьох видах застосувань. Наведемо приклад розробки багатопотокового сервера за принципом «потік для запиту» (thread per request).

У таких серверах є головний потік, який очікує безпосередніх запитів клієнта на отримання даних (виконуючи синхронну операцію read О або recvfromO для сокетів). Після отримання кожного запиту головний потік створює новий робочий потік для обробки його запиту, після чого продовжує очікувати подальших запитів. Робочий потік обробляє запит і завершується. Такий підхід застосовують для зв'язку без збереження стану, коли обробка одного запиту не залежить від обробки іншого. Ось псевдокод сервера, що працює за таким принципом:

void concurrent_server() {

 for (; ;) {

read (fd. &request); // синхронно очікувати запит

// створити потік для обробки запиту

create_thread (worker_thread. request):

}

}

// функція потоку обробки запиту

void worker_thread(request_t request) {

process_request(request); // обробити запит

}

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

У зв'язку з використанням багатопотоковості для організації асинхронного введення-виведення виникають ще деякі проблеми.

♦ Не завжди варто додавати багатопотоковість в однопотокове застосування тільки тому, що в ньому знадобилося виконати асинхронне введення-виведення.

♦ Потрібно реалізовувати синхронізацію потоків.

  •  Може знизитися надійність застосування.
  •  Кваліфікація програмістів може виявитися недостатньою для реалізації багатопотоковості.

Усе це призводить до значного поширення технологій, альтернативних до цього підходу. Розглянемо їх.

10.3. Введення-виведення із повідомленням

Першою технологією, яку можна використати для організації введення-виведення без блокування і яка не вимагає організації багатопотоковості, є введення-виведення із повідомленням (notification-driven I/O) [77]. Ця технологія має й інші назви, наприклад мультиплексування введення-виведення (I/O multiplexing).

Загальні принципи введення-виведення із повідомленням

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

У цьому разі виконання введення-виведення поділяють на кілька етапів.

  1.   Спеціальний системний виклик (виклик повідомлення) визначає, чи можна виконати синхронне введення-виведення хоча б для одного дескриптора із заданого набору без блокування потоку. У POSIX визначено виклики повідомлення poll() і select().
  2.   Як тільки хоча б один дескриптор із набору стає готовий до введення-виведення без блокування, виклик повідомлення повертає керування; при цьому поточний потік може визначити, для яких саме дескрипторів може бути виконане введення-виведення або які з них змінили свій стан (тобто отримати повідомлення про стан дескрипторів).
  3.   Потік, що викликає, може тепер у циклі обійти всі дескриптори, визначені внаслідок повідомлення на етапі 2, і виконати введення-виведення для кожного з них, блокування поточного потоку ця операція в загальному випадку не спричинить.

Проілюструємо застосування цієї технології на прикладі реалізації реактивного сервера [54]. Такий сервер відповідає на запити клієнтів в одному потоці виконанням у циклі опитування стану набору дескрипторів, визначення тих із них, на які прийшли запити, та подальшого виконання цих запитів.

Введення-виведення із повідомленням про стан дескрипторів

Спочатку реалізуємо реактивний сервер на основі технології введення-виведення із повідомленням про стан дескрипторів (state-based notification). Це традиційний підхід, який використовується багато років. Необхідно виконати такі кроки.

  1.   Підготувати структуру даних (назвемо її fdarr) з описом усіх дескрипторів, стан яких потрібно відстежувати.
  2.   Передати fdarr у системний виклик повідомлення (у POSIX до таких викликів належать уже згадані select () і poll ()). Після виходу із виклику повідомлення fdarr міститиме інформацію про стан усіх відстежуваних дескрипторів (які з них готові до виконання введення-виведення без блокування, а які – ні).
  3.   Для дослідження результатів повідомлення обійти в циклі всі елементи fdarr і для кожного із них визначити готовність відповідного дескриптора; якщо він готовий – виконати для нього введення-виведення.

Ось псевдокод реактивного сервера із використанням повідомлення про стан дескрипторів:

void reactive_server () {

// цикл опитування набору дескрипторів fdarr. підготовленого раніше

for ( ; : ) {

select (&fdarr);        // прослуховування набору

// цикл визначення активних дескрипторів

for (і=0; і <= count(fdarr); i++) {

if ( requestjs_ready (fdarr[i]) ) { // якщо був запит

read (fdarr[i], &request); // одержати дані запиту

process_request (request); // обслужити клієнта

}

}

}

}

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

select () повертає інформацію про ті запити, які потрібно обслужити;

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

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

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

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

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

Введення-виведення із повідомленням про події

Для того щоб підвищити ефективність цієї схеми, запропоновано інший підхід -введення-виведення із повідомленням про події (event-based notification) [77].

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

Найвідомішими є приклади реалізації такого підходу для FreeBSD (kqueue) і для Linux 2.6 (epoll).

Виконання введення-виведення в цьому разі зводиться до таких кроків.

1. Спеціальний системний виклик (у Linux epol l_create()) створює структуру даних у ядрі; зазвичай як параметр у такий виклик передають максимальну кількість дескрипторів, які потрібно контролювати. Таку структуру даних на-зивають прослуховувальним об'єктом.

  1.   Після створення такого об'єкта для нього потрібно сформувати набір контрольованих дескрипторів, для кожного з них вказують події, які цікавлять потік, що виконував виклик. У Linux це робиться окремим викликом epoll_ctl(), один із можливих варіантів виконання якого додає дескриптор у набір.
  2.   Виклик повідомлення (у Linuxepoll_wait()) при цьому повертає інформацію тільки про ті дескриптори, які змінили стан із моменту останнього виклику (а не про всі дескриптори, як для select() або poll ()).

Ось псевдокод реактивного сервера із використанням повідомлення про події:

void reactive_server2 () {

epfd = epoll_create();   // створити прослуховувальний об'єкт

// додати дескриптори в прослуховувальний об'єкт

for (i=0; i<=count(fdarr);i++)

epoll_ctl(epfd. ADD.  fdarr[i]);

// цикл опитування набору дескрипторів у прослуховувальному об'єкті

for ( : ; ) {

epoll_wait (epfd. Sactive);    // визначення активного набору

// цикл обслуговування запитів

for (і=0; і <= count(active); i++) {

read (active[i]. &request): // одержати дані запиту

process_request (request);  // обслужити клієнта

}

}

}

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

10.4. Асинхронне введення-виведення

Асинхронне введення-виведення реалізоване у деяких UNIX-системах (є стандарт POSIX для таких операцій). Одна з найповніших реалізацій цієї технології доступна також в системах лінії Windows ХР, де її називають введенням-виведен-ням із перекриттям (overlapped I/O). Основна ідея тут полягає в тому, що потік, який почав виконувати введення-виведення, не блокують до його завершення. Асинхронне введення-виведення зводиться до виконання таких дій.

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

Операція може бути перервана до свого завершення.

Основним підходом до отримання повідомлення про завершення асинхронного введення-виведення є виконання операції очікування завершення введення-виведення. При цьому потік призупиняють до завершення асинхронної операції.

Контрольні питання:

1. Синхронне введення-виведення.

2. Багатопотокова організація введення-виведення.

3. Загальні принципи введення-виведення із повідомленням.

4. Введення-виведення із повідомленням про стан дескрипторів.

5. Введення-виведення із повідомленням про події.

6. Асинхронне введення-виведення.


 

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

13980. Рок-музыка 18.85 KB
  Рокмузыка Рокмузыка обобщающее название ряда направлений популярной музыки. Слово rock указывает на характерные для этих направлений ритмические ощущения связанные с определённой формой движения. Такие признаки рокмузыки как использование электромузыкальны
13981. Праздники в Индии 112.5 KB
  Праздники в Индии. Индия мультинациональное и мультикультурное государство поэтому здесь отмечаются праздники различных религий. Помимо религиозных в Индии имеется три официальных национальных праздника: День независимости Индии День Республики и День р...
13982. История джаза 35.63 KB
  План: I. Введение. II. Главная часть: III. Заключение. I. Введение. Джаз никогда не был популярной музыкой. Несомненно время от времени отдельные формы джаза становились популярными: так было с €œджазовой€ музыкой 20х со €œсвингом€ 1935 1945 гг. так обстоит дело ...
13983. Певица Аврил Лавин 516.3 KB
  Выполнила ученица 8 класса А средней школы №50 Исаева Мария Певица Аврил Лавин настоящее имя Avril Ramona Lavign родилась в Певица Аврил Лавин настоящее имя Avril Ramona Lavign родилась в сентябре 27 числа 1984 года. Кроме нее в семье еще ...
13984. Pitbull. Armando Christian Perez 254.93 KB
  Доклад По музыке На тему: Pitbull. Подоготовил ученик 7 В класса. Бекиров Руслан Доклад по музыке на тему: Pitpul Armando Christian Perez Певец музыкальный продюсер автор песен. Сценическое имя: Pitbull.Начало карьеры: 2003 год.День рождения: 15 января 1...
13985. Теодор Адорно как теоретик социологии музыки 40 KB
  Эссе на тему:Теодор Адорно как теоретик социологии музыки Сущность общества становится сущностью музыки Теодор Адорно Человек и музыка Неразрывные понятия ведь без человека нет музыки а без музыки нет человека. И я не преувеличиваю. Подумайте: с древне...
13986. Глинка Михаил Иванович 29.91 KB
  Глинка Михаил Иванович Глинка Михаил Иванович 18041857 русский композитор. Первые музыкальные впечатления Глинки связаны с народной песней. Ещё в детстве приобщился к профессиональной музыке. Юные годы Глинки прошли в Петербурге. Благотворно отразились на формирован
13987. Теория и методика музыкального воспитания детей дошкольного возраста 786.25 KB
  Гогоберидзе А.Г. Теория и методика музыкального воспитания детей дошкольного возраста: Учеб. пособие для студ. высш. учеб. заведений /А. Г. Гогоберидзе В.А.Деркунская. М.: Издательский центр Академия 2005. 320 с. Оглавление ОТ АВТОРОВ Часть 1. ТЕОРЕТИЧЕСКИЕ ОСНОВЫ МУЗЫК...
13988. Урок. Как выбрать правильную гитару 73.5 KB
  Как выбрать правильную гитару У вас есть желание купить себе качественную гитару На первый взгляд это не проблема. Бытует мнение что тот у кого толстый бумажник имеет огромные преимущества. Узнавая все новые тонкости и мелочи в процессе выбора гитары самодовольн...