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. Асинхронне введення-виведення.


 

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

21823. Возведение железобетонных монолитных зданий 70 KB
  Вместе с тем монолитное домостроение имеет особенности сдерживающее его более широкое применение: увеличенная трудоёмкость некоторых процессов опалубочные арматурные работы уплотнение бетонной смеси и др.; необходимость тщательного выполнения технологических регламентов производства работ и контроля их качества; относительно сложные технологические процессы что диктует повышенную требовательность к квалификации работников. Дальнейшее развитие монолитного строительства базируется на совершенствовании технологий опалубочных арматурных...
21824. Применение различных опалубок в монолитном домостроении 139 KB
  Щитовые опалубки Щитовые опалубки наиболее широко применяются в жилищном гражданском и промышленном строительстве. Для повышения производительности труда щиты опалубки можно предварительно собирать в крупноразмерные плоские опалубочные панели или в пространственные блоки которые устанавливаются и демонтируются с помощью кранов. Мелкощитовые опалубки отличаются высокой универсальностью их можно использовать для возведения самых различных конструкций – фундаментов колонн стен балок перекрытий. Существенным недостатком мелкощитовых...
21826. Возведение зданий методом подъёма перекрытий 136 KB
  Этот метод очень эффективен в сейсмических районах благодаря применению цельных неразрезных плит перекрытий выполняющих роль горизонтальных диафрагм обеспечивающих поперечную жёсткость здания а также при необходимости строительства в стеснённых условиях исключающих применение кранов. 5 а 2 3 б 1 2 в 4 г ...
21827. ВОЗВЕДЕНИЕ ВЫСОТНЫХ ЗДАНИЙ 85 KB
  Конструктивно современные высотные здания являются каркасными – это железобетонный стальной или комбинированный каркас с пространственным ядром жёсткости или с плоскими диафрагмамисвязями рис. В большинстве высотных зданий предусмотрено ядро жёсткости которое воспринимает горизонтальные нагрузки от примыкающих частей здания и обеспечивает устойчивость и пространственную жёсткость всего здания в процессе монтажа и эксплуатации. Ядра жёсткости обычно выполняют из железобетона хотя в металлических каркасах ядро может быть стальным....
21828. СТРОИТЕЛЬСТВО ДЕРЕВЯННЫХ ЗДАНИЙ 42 KB
  Технология производства строительномонтажных работ включает в себя следующие основные процессы: земляные работы под фундаменты; устройство фундаментов с гидроизоляцией; установка обвязочного бруса по периметру стен; укладка элементов пола 1 этажа по обвязочному брусу с утеплением и изоляционными слоями; устройство чёрного пола; монтаж стен и перегородок первого этажа; устройство проёмообразователей под окна и двери из пилёного леса перемычек и стоек ; окончательное проектное соединение элементов между собой; монтаж или устройство...
21829. МОНТАЖ БОЛЬШЕПРОЛЁТНЫХ КОНСТРУКЦИЙ 78.5 KB
  Конструктивно покрытия выполняются следующих типов рис.: Металлические фермы и балочные системы иногда предварительно напряжённые с затяжками; Арочные и купольные системы; Перекрёстностержневые системы типа структур; Железобетонные пространственные покрытия оболочки арки складки ; Висячие покрытия мембранные тонколистовые с жесткими нитями подвесные – плоскостные и пространственные; Вантовые покрытия вантовые сетки вантовобалочные системы висячие оболочки вантовые фермы комбинированные системы; Пневматические...
21830. МОНТАЖ ВЫСОТНЫХ СООРУЖЕНИЙ – МАЧТ, БАШЕН, ТРУБ 51 KB
  МОНТАЖ ВЫСОТНЫХ СООРУЖЕНИЙ – МАЧТ БАШЕН ТРУБ 15. При возведении высотных сооружений наиболее распространены следующие методы: наращивание конструкций в проектном положении – поярусное возведение снизу вверх; монтаж поворотом – предварительная сборка сооружения на земле в горизонтальном поолжении с последующим поворотом вокруг шарнира в вертикальное проектное положение; подращивание конструкции – сборка в вертикальном положении начиная с самых верхних секций их подъём подведение под них последующих секций их общий подъём до...
21831. ВОЗВЕДЕНИЕ МЕТАЛЛИЧЕСКИХ РЕЗЕРВУАРОВ 37.5 KB
  Днище и корпус устраивают из цельносварных рулонированных на заводе полотнищ. Изготавливают рулонные заготовки на специальных двухярусных стендахконвейерах имеющих посты раскроя; сборки и прихватки листов; сварки с одной стороны; сварки с другой стороны; испытания и рулонирования. Готовую заготовку сворачивают в рулон на центральную стойку покрытия или шахтную лестницу и закрепляют от самопроизвольного разворачивания специальными планками на сварке. Готовые к отправке рулоны имеют габариты: высота – 3м; длина – 12 или 18м; вес – 21 или 47т.