Показаны сообщения с ярлыком Windows NT. Показать все сообщения
Показаны сообщения с ярлыком Windows NT. Показать все сообщения

Чем авторизация отличается от аутентификации?

Операционные системы семейства Windows 2000 с самого начала разрабатывались с учетом требований документа TCSEC (Trusted Computer System Evaluation Criteria - Критерии оценки надежной системы) министерства обороны США. Для обеспечения безопасности компьютерных систем, созданных на базе Windows 2000, в нее включены средства защиты, поддерживающие три основных компонента.
  • Аутентификация.
  • Авторизация.
  • Аудит.

Рассмотрим эти компоненты системы защиты по очереди.

Полная и абсолютная отдача

Вот как описывает самоотдачу программистов, работавших над созданием ОС Windows NT, Паскаль Захарий (Pascal Zachary):

«Работа пронизала само их существование. Друзья отошли на второй план. Супружеские узы поистрепались или совсем разорваны. Детям не уделялось внимание или они отодвигались в сторону. Хобби забыты. Компьютерная программа стала значить все. Если и лелеялись какие-то личные мечты, то лишь как средство отвлечься от создания NT.» 

После завершения проекта Windows NT одни разработчики ушли из компании, а другие были настолько опустошены, что вовсе ушли из программирования.

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

"Профессиональная разработка программного обеспечения"

Win32 threads

Когда стартует процесс посредством функции CreateProcess, он имеет один поток для выполнения команд. Поток состоит из двух объектов: объект ядра (через него система управляет потоком) и стек, в котором хранятся параметры, функции и переменные потока. 

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

Вернемся к функции CreateThread и рассмотрим ее параметры.
  • Первый параметр — указатель на структуру PSECURITYATTRIBUTES, которая определяет атрибуты защиты и свойства наследования, для установки значений по умолчанию достаточно передать NULL. 
  • Второй параметр типа DW0RD определяет, какую часть адресного пространства поток может использовать под свой стек. 
  • Третий параметр PTHREADSTART_ROUTIME pfnStartAddr — указатель на функцию, которую необходимо привязать к потоку и которую он будет выполнять. Эта функция должна иметь вид DWORD WINAPI ThreadFunc(PVOID pvParam), она может выполнять любые операции; когда она завершится, то возвратит управление, а счетчик пользователей объекта ядра потока будет уменьшен на 1, в случае, когда этот счетчик будет равен 0, данный объект будет уничтожен. 
  • Четвертый параметр функции CreateThread — указатель на структуру PVOID, содержащую параметр для инициализации выполняемой в потоке функции (см. описание третьего параметра). 
  • Пятый параметр (DWORD) определяет флаг, указывающий на активность потока после его создания. Последний, шестой параметр (PDWORD) — адрес переменной, куда будет помещен идентификатор потока, если передать NULL, тем самым мы сообщим, что он нам не нужен. В случае успеха функция возвращает дескриптор потока, с его помощью можно манипулировать потоком; при фейле функция возвращает 0.

Существуют четыре пути завершения потока, три из которых нежелательные: это завершение потока через вызов функции ExitThread, через вызов TerminateThread, при завершении родительского процесса без предварительного завершения потока. Лишь 1 путь – самозавершение потока, которое происходит при выполнении назначенных ему действий, является благоприятным. Потому что только в этом случае гарантируется освобождение всех ресурсов операционной системы, уничтожение всех объектов C/C++ с помощью их деструкторов.

Еще пара слов о создании потока. Функция CreateThread находится в Win32 API, при этом в библиотеке Visual C++ имеется ее эквивалент _beginthreadex, у которой почти тот же список параметров. Рекомендуется создавать потоки именно с ее помощью, поскольку она не только использует CreateThread, но и выполняет дополнительные операции. Кроме того, если поток был создан с помощью последней, то при уничтожении вызывается _endthreadex, которая очищает блок данных, занимаемый структурой, описывающей поток.

Потоки планируются на выполнение с учетом приоритета. Если бы все потоки имели равные приоритеты, то для выполнения каждого (в WinNT) выделялось бы по 20 мс. Но это не так. В WinNT имеется 31 (от нуля) поточный приоритет. При этом 31 — самый высокий, на нем могут выполняться только самые критичные приложения — драйверы устройств; 0, самый низкий, зарезервирован для выполнения потока обнуления страниц. Тем не менее разработчик не может явно указать номер приоритета для выполнения своего потока. Зато в Windows есть таблица приоритетов, где указаны символьные обозначения сгруппированных номеров приоритетов. При этом конечный номер формируется не только на основе этой таблицы, но и на значениях приоритета родительского процесса. Значения скрыты за символьными константами по той причине, что Microsoft оставляет за собой право их изменить и пользуется им от версии к версии своей операционки. При создании поток получает обычный (normal) уровень приоритета. Его можно изменить функцией SetThreadPriority, принимающей два параметра: HANDLE hThread — дескриптор изменяемого потока, int nPriority — уровень приоритета (из таблицы). С помощью функции GetThreadPriority можно получить текущий приоритет, передав в нее дескриптор нужного потока. Перед изменением приоритета потока его надо приостановить, это делается функцией SuspendThread. После изменения приоритета поток надо снова отдать планировщику для планирования выполнения функцией ResumeThread. Обе функции получают дескриптор потока, с которым работают. Все описанные операции кроме приостановки и возобновления применимы и к процессам. Они не могут быть приостановлены/возобновлены, поскольку не затрачивают процессорное время, поэтому не планируются.

Модель вытесняющей многопоточности в Windows NT 6.1

Windows NT 6.1 использует модель вытесняющей многопоточности. Когда запускается приложение, стартует процесс, в нем могут выполнять свою работу один или несколько потоков, все они разделяют общую память и общее адресное пространство. Поток же, в свою очередь, — это обособленная последовательность команд, выполняемая независимо.

Существует три вида потоков:
  • пользовательского уровня — создается в пользовательской программе (на уровне пользователя). Эти потоки в Windows NT проецируются на потоки уровня ядра, так их видит процессор (Ни о каких потоках процессор не знает вообще! У процессора есть контекст исполнения (состояние регистров) и оперативная память. Загрузили программу в память, установили регистры - пошло выполнение. Пришло прерывание - посмотрела ОС, что пора переключать, сохранила контекст, загрузила новый - пошло исполнение другого потока. Такого объекта, как "поток", на уровне процессора не существует. А проецируются друг на друга структуры в памяти, т.е. чисто искусственные образования ОС.);
  • поток ядра — управляется ядром операционной системы;
  • аппаратный поток — единица, исполняемая на процессоре.

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

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