Взаимодействие с пользователем 


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



ЗНАЕТЕ ЛИ ВЫ?

Взаимодействие с пользователем



Взаимодействие с пользователем

В операционных системах

Рекомендуемая литература:

1. В.Г.Олифер, Н.А.Олифер. Сетевые операционные системы. Учебное пособие.-СПб.:БХВ-Петербург, 2006.-536с.

2. В.А.Шеховцов. Операційні системи.Підручник.-К.:Виканавча група ВНV. 2005. 576с.

3. Столлингс В. Операционные системы. М.: Вильямс, 2001. -672с.

Раздел 8

Взаимодействие с пользователем в операционных системах

Средства терминального ввода-вывода

Командный и графический интерфейсы пользователя

Процессы без взаимодействия с пользователем

 

Терминальный ввод-вывод

В этом разделе остановимся на базовой технологии для организации взаимодействия с пользователем в операционных системах - терминальном вводе-выводе. Хоть история этой технологии насчитывает несколько десятилетий, однако она продолжает оставаться важной составляющей современных ОС.

 

Организация терминального ввода-вывода

Сначала рассмотрим принципы организации терминального ввода-вывода, которые не зависят от конкретной ОС.

Понятие терминала

Исторически терминалы (terminals) использовали для организации многопользовательской работы с мэйнфреймами или миникомпьютерами. Это были аппаратные устройства, которые состояли из клавиатуры и дисплея, которые подключали к компьютеру через интерфейс последовательного порта.

Особенное распространение такие терминалы получили в 70-80-ые годы: все разработаные в то время операционные системы включали средства их поддержки, было создано много прикладного программного обеспечения, рассчитанного на работу с ними.

Такие терминалы работают в текстовом режиме, за который обмен данными и их отображение на программном уровне происходят посимвольно. Для отображения используют экран размером (обычно 25 на 80) в символах, причем отображаться могут только стандартные символы (коды 127-255) в соответствии с таблицей ASCII-символов (Американский стандартный код для обмена информацией). За представление на экране расширенного набора символов с этими кодами, в частности символов кириллицы, отвечает символьная таблица, которая используется терминалом.

Есть специальные символы (управляющие коды) и последовательности символов, которые не отображаются, а руководят выведением на экран терминала. К управляющим кодам принадлежат такие символы, как возвращение каретки, перевод строки, Васksрасе и тому подобное. Управляющие последовательности называют также ESC-последовательностями (они начинаются с символа - ESC (код 27 ASCІІ )). Передавая такие последовательности терминала, можно перемещать курсор в произвольную позицию экрана, руководить яркостью отображения символов, для некоторых моделей терминалов - цветами и тому подобное.

Эмуляция терминала

В современных условиях аппаратные терминалы применяют редко. Однако интерфейс связи с терминалами (терминальный ввод-вывод) не потерял своего значения и до сих пор. Это объясняется тем, что текстовый режим работы очень удобен для решения многих задач (организации администрирования системы, отдаленного доступа к ней и тому подобное), а также широким выбором программного обеспечения, которое использует этот режим.

Для упрощения организации терминального ввода-вывода у современных ОС широко используют эмуляцию терминала. Программное обеспечение (эмулятор) принимает данные от соответствующего терминала и отображает на дисплее компьютера информацию согласно управляющих сигналов, определенных для терминала (для этого может быть выделено отдельное окно на графическом экране). В итоге программное обеспечение, рассчитанное на работу с терминалом, можно использовать с таким эмулятором без изменений. Одновременно в системе может быть запущено несколько эмуляторов терминала (например, каждый в своем окне), и пользователь имеет возможность переключаться между ними, выполняя ввод-вывод. Самая распространенная эмуляция терминала - vt100. Программное обеспечение, рассчитанное на использование этого терминала, с большой вероятностью будет работать с любым эмулятором.

Поэтому говоря о вводе с терминала и выводе на терминал, имеем ввиду, что обмен данными будет почти всегда происходить не с аппаратным терминалом, а с его эмулятором.

Терминальный ввод

Есть два подхода к организации терминального ввода.

· В режиме без обработки, или неканоническом режиме (non-canonical mode), данные передаются программе без изменения (включая управляющие коды, такие, как перевод каретки или Ваcksрасе). За интерпретацию этих кодов отвечает программа. Такой режим сложнее, но более гибкий. Чаще всего его используют текстовые редакторы.

· В случае использования режима с обработкой, или канонического режима (canonical mode), данные дополнительно будут обрабатываться перед тем как поступить в программу. Такая обработка происходит после нажатия пользователем клавиши Еnteг (ввод символа перевода строки), при этом управляющие коды будут интерпретированы и в соответствии с ними изменена вся введеная строка (например, если в ней трижды подряд случится Васksрасе, то эти три символа и еще три, введенные перед ними, из строки будут изъяты). Такой режим проще для программиста, в программу в данном случае попадает уже подготовленная символьная строка.

Примером программного обеспечения, которое реализует компромисс между этими режимами, может быть распространенная в UNIX-системах библиотека readline. Она предоставляет расширенные средства редактирования введенной строки, которые нуждаются в поддержке неканонического режима, но ее программный интерфейс аналогичен к вводу в каноническом режиме (в программу попадает подготовленная в результате редактирования строка).

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

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

Терминальный вывод

Для выведения на терминал тоже используют буферизацию. Буфер вывода заполняют в том случае, когда терминал не готов принять символ и по мере его готовности символы из буфера передают терминалу. Отображая данные, он интерпретирует управляющие сигналы, после чего показывает информацию, выделяет цветами отдельные участки, перемещает курсор и тому подобное.

Главная проблема заключается в том, что разные модификации терминалов воспринимают разные наборы управляющих сигналов. Для ее решения у современных ОС обычно создают базу данных терминалов, которая содержит список терминалов и сигналов, которые отвечают каждому из них. В UNIX-системах такую базу называют terminfo.

Логическая структура терминального ввода-вывода показана на рис. 8.1.

Рис. 8.1 Терминальный ввод-вывод

Псевдотерминалы

Раньше уже речь шла о принципе работы протокола telnet. Возникает вопрос: каким образом telnet-сервер перехватывает данные, которые процессы отсылают на терминал? Для ответа нужно ознакомиться с концепцией псевдотерминалов.

Псевдотерминалом (pty) называют специальное устройство, которое создает и контролирует процесс режима пользователя (ведущий процесс, pty master).

Для всех других процессов (ведомых процессов, pty slaves) это устройство имеет вид реального терминала. В итоге все данные, которыми ведомые процессы обмениваются с псевдотерминалом, оказываются под полным контролем ведущего процесса. В частности, ведущим процессом в случае telnet является telnet-сервер, ведомым - процесс, который запускают в telnet-сессии. В итоге сервер имеет возможность перехватывать все данные, которые будут созданы во время сессии, и отсылать их в сеть.

Псевдотерминал отображают двумя специальными файлами устройств:

-файлом ведущего (pty master file)

-файлом ведомого (pty slave file).

С файлом ведущего работает ведущий процесс, все другие процессы работают с файлом ведомого. Все данные записанные в файл ведомого, могут быть считаны из файла ведущего и наоборот.

Есть несколько интересных применений псевдотерминалов.

Например, есть утилита screen, что перехватывает весь ввод-вывод интерактивной программы или сессии пользователя и хранит его в файле. Для этого screen создает псевдотерминал и вынуждает программу обмениваться данными не с консолью, а с этим терминалом.

Разработка функции окна

Функция окна определяется так:

long CALLBACK wnd_proc(HWND hwnd. UINT msgcode. WPARAM wp. LPARAM lp) {

// обработка сообщений, адресованных окну

}

где: hwnd - дескриптор соответствующего окна;

msgcode - код сообщения, которое поступило;

wp, lp - дополнительные данные, которые могут сопровождать сообщение (отвечают полям wParam и lParam структуры сообщения).

В коде этой функции проверяют код сообщения и в зависимости от его значения выполняют действия.

switch (msgcode) {

case код-уведомление 1:

// действия по обработке уведомления

case код-уведомления2:

// действия по обработке уведомления2 и т.д.

}

Есть много разных сообщений, здесь реализуем выполнение действий в случае получения двух из них:

Wm_PAINT - поступает окну каждый раз, когда его содержание нужно изменить (в случае отображения, активизации, перемещения и тому подобное);

Wm_CLOSE - поступает в случае закрытия окна пользователем.

Об обработке WM_PAINT будет идти речь отдельно, а пока еще остановимся на действиях по получении WM_PAINT и обработке сообщений по умалчанию.

В случае получения сообщения WM_PAINT необходимо прекратить выполнение приложения, для чего нужно прервать цикл обработки сообщений.

Стандартный способ реализовать такое прерывание - воспользоваться функцией PostQuitMessage(), которая помещает в цикл сообщение с кодом WM_QUIT.

Как параметр эта функция принимает значение, которое станет кодом возвращения применения.

switch (msgcode) {

case WM_CLOSE:

PostQuitMessage(O):

return 0;

}

Когда в окно поступило сообщение, которое функция окна не может обработать, в ней нужно обеспечить обработку такого сообщения, предусмотренную ОС (обработка по умолчанию). Для ее реализации необходимо вызывать стандартную функцию окна, то есть выполнить функцию DefWindowProc(), куда передать те же параметры, которые были получены функцией окна.

switch (msgcode) {

// обработка известных сообщений

}

// обработка всех других сообщений

return DefWindowProc(hwnd. msgcode. wp. lp);

Система X Window

У некоторых ОС графические подсистемы не являются интегрированными и не выполняются в режиме ядра. Таким примером является система X Window (X Window System), которую доныне широко используют в UNIX-системах.

Оконные менеджеры

Команды, посланные клиентами сервера, обычно связанные с необходимостью отображения информации в окне применения - участке екрана, которым владеет соответствующее применение. Важным свойством системы X Window есть то, что Х-сервер не отвечает за работу с такими окнами, для этого используют специальное клиентское приложение - оконный менеджер (window manager). В обязанности такого менеджера входит поддержка базовых операций над окнами (их перемещения, закрытия или изменения размеров), а также «декорирование» окон (отображение рамки, заглавия и тому подобное).

Оконные менеджеры почти всегда выполняются на той же машине, что и Х-сервер, они запускаются обычно сразу после запуска сервера. Во всем другому это обычные Х-клиенты, которые обмениваются с сервером командами, связанными с отображением окон, обработкой команд пользователя из их перемещения и тому подобное. С другой стороны, они не отвечают за то, которое происходит внутри окон приложений (отображение информации, обработка действий пользователя), - соответствующие команды передаются серверу от приложения клиента прямо, за их генерацию отвечают инструментальные библиотеки, о чем будет идти речь дальше.

Решение выделить поддержку оконных операций в отдельное приложение дало возможность достичь дополнительной гибкости работы с системой. Есть многие разные оконные менеджеры, среди самых распространенных можно выделить fvwm, sawfish, enlightenment. Некоторые из них реализуют лишь базовую функциональность управления окнами, другие предоставляют пользователю много возможностей (запуск приложений, организации рабочего стола и тому подобное).

Сессии и группы процессов

Каждый процесс принадлежит к группе процессов, которую помечают идентификатором группы процессов (pgid). Ядро может выполнять определенные действия над всеми процессами группы (например, отсылать им всем сигнал). Каждая группа может иметь лидера группы (у этого процесса идентификатор (pid) совпадает с идентификатором группы). Обычно процесс наследует идентификатор группы от своего предка, он может также явно изменить свою группу системным вызовом setpgrp().

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

Несколько групп процессов объединяют в сессию. Для сессии задают идентификатор сессии (sid). Обычно процессы сессии отвечают набору процессов, которые создал пользователь во время интерактивного сеанса работы с системой.

Каждый керуючий терминал связан с сессией и с одной группой процессов этой сессии (такую группу называют еще интерактивной (foreground) группой, все другие называют фоновыми (background), с ними терминалы не связаны). Противоположное, как и для групп, не всегда верное - сессия может быть вообще не связана с управляющим терминалом, в этом случае у нее отсутствует интерактивная группа.

У каждой сессии есть лидер сессии, который отвечает за управление сессией и изоляцию ее от других; его идентификатор совпадает с идентификатором сессии. Если лидер сессии связан с терминалом, в случае выхода пользователя из системы этот процесс получает сигнал SIGHUP. Обычной реакцией на этот сигнал будет завершение работы процесса-лидера и всех процессов его сессии.

Когда лидер сессии с терминалом не связан, сигнала о выходе он не получит и сможет продлить выполнение по окончании сеанса работы. Это особенно важно для фоновых процессов.

Взаимосвязь между сессиями, группами процессов и управляющими терминалами показанная на рис. 8.3.

Рис.8.3 Сесии, группы процессов и управлдяющие терминалы

Создание новой сессии

Посмотрим, как пользователь может создать новую сессию и для чего это может понадобиться. Новую сессию создают с помощью системного вызова setsid(). Во время его выполнения

· создают сессию, и текущий процесс становится её лидером;

· создают новую группу процессов в рамках сессии, и текущий процесс становится ее лидером;

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

В итоге будет создана сессия без управляющего терминала и с одной фоновой группой внутри нее, что содержит на этот момент один процесс. Этим как текущий процесс, так и свои потомки будут защищены от сигналов из клавиатуры и сигнала о выходе из системы, то есть будут корректно переведены в фоновый режим. Именно так необходимо реализовывать фоновые процессы, которые предусматривают использовать независимо от наличия интерактивных сеансов пользователей в системе.

Отметим, что, если процесс уже является лидером группы процессов, вызов setsid() приведет к ошибке. Для того, чтобы ее избежать, рекомендуют сначала создать потомка процесса с помощью fork () (он гарантированно не будет лидером группы), в нем вызывать setsid(), а предка завершить.

Службы Windows XP

Аналогом демонов у Windows XP являются службы (services) - фоновые процессы, которые могут выполняться даже тогда, когда с системой не работает ни один пользователь. Из раздела 2 уже известно о том, что за управление службами отвечает менеджер служб (Service Control Manager). Он принимает управляющие команды от приложений и в соответствии с ними выполняет действия со службами (например, запускает на выполнение или останавливает).

Интерфейс пользователя менеджера служб реализован двумя способами:

♦ С с помощью окна управления службами (Services), которое вызывают через подменю Administrative Tools главного меню системы (это окно отображает список служб, дает возможность запускать и останавливать отдельные службы, узнавать об их свойствах и тому подобное);

♦ С помощью утилиты net.exe, что входит в поставку Windows XP; например, команда net start имя_служби дает команду менеджеру запустить соответствующую службу, net stop имя_служби - остановить ее.

Для управления службами необходимо иметь административные права в системе.

Реализация кода службы

Перейдем к непосредственной реализации кода службы. В первую очередь необходимо определить несколько переменных. Среди них структура SERVICE_STATUS, которая отображает состояние службы, дескриптор состояния службы (переменная типа Service_status_handle) и флажок, который определяет, можно ли продолжать выполнение основной функции службы (переменная running). Эти переменные определяются как глобальные, потому что к ним нужен доступ из нескольких функций (главной функции службы и обработчика команд управления).

SERVICE_STATUS status = { 0 }:

SERVICE_STATUS_HANDLE sth;

bool running = true;

В коде функции main() необходимо определить массив структур SERVICE_TABLE_ENTRY. Элементами этой структуры является имя службы и указатель на ее главную функцию. Для последнего элемента массива оба этих поля задаются как NULL.

Эту структуру нужно передать как параметр в функцию StartServiceCtrLDispatcher(). После этого будет выполняться код главной функции службы.

void maino {

SERVICE_TABLE_ENTRY disp_table[] =

{{"mysvc".svc_main}.{NULL.NULL}:

StartServiceCtrLDispatcher(disp_table); }

Главная функция службы

Главную функцию службы вызывают во время запуска службы (в результате выполнения StartServiceCtrLDispatcher()) и выполняют к ее остановке. ее код реализует основную функциональность службы (ожидает соединений от клиентов, выполняет запросы и тому подобное). Определение этой функции имеет такой вид:

void WINAPI svc_main(DWORD argc. LPTSTR argv[]){

// код основной функции службы

}

В этой функции нужно выполнить ряд шагов. В первую очередь задаются некоторые параметры службы установлением полей глобальной структуры SERVICE_STATUS. К ним принадлежат:

dwServiceType - тип службы (SERVICE_WIN32_OWN_PR0CESS для обычных служб, которые выполняются в отдельном процессе);

dwCurrentState - текущее состояние службы (в этот момент она ожидает начала выполнения, и этот параметр возлагают ровными SERVICE_START_PENDING);

dwControlsAccepted - допустимые управляющие команды, которые входят в функцию-обработчик команд (SERVICE_ACCEPT_STOP значит, что будет обрабатываться только команда Stop).

Заполнение структуры SERVICE_STATUS выполняется так:

status.dwServiceType = SERVICE_WIN32_OWN_PR0CESS:

status.dwCurrentState = SERVICE_START_PENDING:

status.dwControlsAccepted - SERVICE_ACCEPT_STOP;

После этого необходимо зарегистрировать в системе обработчик керуючих команд этой службы с помощью функции Registerservicectrlhandlero, которая принимает имя службы и адрес функции-обработчика, а возвращает глобальный дескриптор статуса службы.

sth = RegisterServiceCtrLHandler("mysvc",svc_ctrlhandler);

После выполнения этого вызова служба будет иметь возможность реагировать на керуючи команды (например, на команду остановки службы).

На этом подготовительный этап завершают. Теперь можно инициализировать службу (создать сетевые соединения, подготовить внутренние структуры данных и тому подобное). После этого службу переводят в состояние выполнения, для чего задают новое значение поля dwCurrentState для структуры SERVICE_STATUS и вызывают функцию SetServiceStatus(), первым параметром которой является глобальный дескриптор статуса службы, а вторым - указатель на структуру SERVICE_STATUS.

//... инициализация службы

status.dwCurrentState - Service_running;

SetServiceStatus (sth. Sstatus):

После этого служба может выполнять любые действия, которых от нее будет требовать программист (принимать соединение от клиентов и тому подобное).

while (running) {

//... работа службы

}

В данном случае переменная runni ng асинхронный будет изменяться в обработчики команд управления.

Исключение службы

Для исключения службы из реестра используют функцию DeleteService(), куда необходимо передать дескриптор службы. Его нужно получить с помощью функции OpenService(), что как параметры принимает дескриптор менеджера служб и имя имеющейся службы:

SC_HANDLE mh – OpenSCManager(NULL. NULL. SC_MANAGER_ALL_ACCESS);

SC_HANDLE sh = OpenService(mh."mysvc",SERVICE_ALL_ACCESS);

Deleteservice(sh);

Closeservicehandle(sh);

Отметим, что если служба в момент исключения находилась в состоянии выполнения, ее лишь помечают для исключения. Фактическое исключение происходит во время следующей загрузки системы.

Выводы

♦ Терминальное введение-выведение реализует взаимодействие с алфавитно-цифровыми устройствами. У современных ОС такие устройства чаще всего являются эмуляторами терминала, работу с которыми осуществляют по одним и тем же правилам. На основе терминального введения-выведения реализуют командный интерфейс пользователя ОС в виде командных интерпретаторов.

 

♦ Есть разные подходы к организации графического интерфейса пользователя, самой распространенной из них является реализация такого интерфейса как интегрированной части системы, которая работает в режиме ядра (так сделано в системах линии Windows XP), и реализация средств его поддержки в режиме пользователя в виде набора библиотек и утилит (примером является система X Window).

 

♦ Разработка фоновых применений, которые не взаимодействуют с пользователем, осуществляется по особенным правилам. В UNIX-системах для таких применений закрыта возможность интерактивного обмена данными с пользователем, в системах линии Windows XP есть специальный компонент, ответственный за управление ими.

Контрольные вопросы и задания

1. Приведите пример программного канала, один из элементов которого должен завершиться аварийно через получение сигнала SIGPIPE. Используйте синтаксис каналов командного интерпретатора.

2. Разработайте применение для Linux и Windows XP, которое:

а) создает потомка, переадресовывает свой стандартный вывод на стандартный ввод этого потомка, выводит сообщение на стандартный вывод и возобновляет предыдущее состояние вывода. Потомок должен отображать на стандартный вывод все данные, полученные на его стандартный ввод;

б) переадресовывает стандартный вывод и стандартный поток сообщений об ошибках в конец файла, имя которого задано в командной строке, после чего выводит сообщение на стандартный вывод и в стандартный поток уведомлений об ошибках;

в) создает двух потомков и переадресовывает стандартный вывод одного из них на стандартный ввод другого (связывая их безымянным каналом). Первый потомок должен выводить произвольное сообщение на стандартный вывод, второй, - отображать на стандартный вывод все данные, полученные на стандартный ввод;

г) хранит стандартный вывод потомка в строке символов и отображает содержание этой строки (так может быть реализована командная подстановка). Потомок должен выводить произвольное сообщение на стандартный вывод.

3. Модифицируйте применение задания 2, бы из раздела 17 так, чтобы стандартный поток сообщений об ошибках был направлен на сервер (заданный ІР-адресом и портом) с использованием сокетов. Разработайте сервер, который будет хранить полученную информацию в файле.

4. Модифицируйте командный интерпретатор для Linux и Windows XP, разработанный во время выполнения задания 10 из раздела 3 и задания 10 из раздела 14, дополнив его функцией переадресування введения-выведения, каналов и командной подстановки. Во время решения задачи пользуйтесь результатами выполнения задания 2 из раздела 17.

5. Сессия командного интерпретатора запущена для отдаленного телнет-клиента. Опишите, какие компоненты ОС на локальном и отдаленном хостах отвечают за отображение стандартного вывода применений, запущенных в этой сессии.

6. Перечислите общие черты и отличия оконной подсистемы Windows XP и системы X Window. Какие преимущества и недостатки имеет каждая из систем?

7. Сессия командного интерпретатора, запущенная на отдаленном хости, отображается в окне эмулятора терминала xterm. Опишите, какие компоненты ОС на локальном и отдаленном хостах отвечают за отображение стандартного вывода применений, запущенных в этой сессии.

8. В какой ситуации стандартный вывод Х-клиента автоматически отображается на текстовой консоли, из которой был запущен Х-сервер, а в которой - нет? Можно ли обеспечить отображение вывода Х-клиента на заданную текстовую виртуальную консоль?

9. Разработайте фоновое применение для Linux и Windows XP, что отслеживает все изменения файлов в заданном каталоге (создание, исключение, изменение размера и тому подобное). Имя каталога может быть задано в командной строке, для Windows XP допустимое его задання в системном реестре. Каждое изменение регистрируют в файле в формате "время: имъя_файлу характер_змини".

10. Модифицируйте сервер, полученный для задания 11 из раздела 16, реализовав его как фоновый процесс для Linux и Windows XP.

 

 

Взаимодействие с пользователем

В операционных системах

Рекомендуемая литература:

1. В.Г.Олифер, Н.А.Олифер. Сетевые операционные системы. Учебное пособие.-СПб.:БХВ-Петербург, 2006.-536с.

2. В.А.Шеховцов. Операційні системи.Підручник.-К.:Виканавча група ВНV. 2005. 576с.

3. Столлингс В. Операционные системы. М.: Вильямс, 2001. -672с.

Раздел 8



Поделиться:


Последнее изменение этой страницы: 2017-01-19; просмотров: 156; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

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