Что такое дескриптор задачи и что он содержит
Дескриптор
Добавлено в закладки: 0
Что такое дескриптор? Описание и определение понятия.
Дескриптор по значению схож с термином «описывающий». Дескриптор – это идентификатор объекта в программировании. К дескрипторам можно отнести большинство тегов, комментариев в языках программирования. Особенностью дескрипторов является то, что они созданы сторонними библиотеками или операционной системой. С подобными объектами можно вести действия, к примеру, создавать или удалять, но при этом то что у них внутри остается скрытым. Дескрипторы могут иметь вид указателей или целых чисел. Каждый документ, который уже хранится в системе, имеет свои дескрипторы, которые формируют его поисковый образ. Характер дескрипторов:
Дескриптор это лексическая единица (слово, словосочетание) информационно-поискового языка, выражающая основное смысловое содержание любого текста. Используется при информационном поиске документов в информационно-поисковых системах.
Дескриптор есть своего рода некое данное, описывающее и однозначно идентифицирующее объект. Как именно дескриптор описывает объект и как идентифицирует, мелко мягкие определяют сами, а остальным достаточно уметь работать с ним, как с “чёрным ящиком”.
Особенности дескриптора
Дескриптор – это слово, словосочетание или целое высказывание, которыми отражают содержание перелагаемого текста в наиболее сжатом виде. В зависимости от характера передаваемого содержания дескрипторы делятся на номинативные дескрипторы, представляющие темы и под темы первичного текста, и предикативные дескрипторы, передающие то, что говорится в пределах каждой темы и под темы. Дескрипторы — это мощный протокол с широкой областью применения. Они являются тем механизмом, который стоит за свойствами, методами, статическими методами, методами класса и вызовом. Дескриптор используется для маскирования внутренней реализации от пользователя. Дескриптор — это один из механизмов абстрагирования. Так же дескриптор – это имя учетной записи, которое Вы указывали при регистрации. Он необходим для добавления игроков в друзья, отправки внутри игровой почты и многих других полезных действий.
Посмотреть в игре его можно в чате, где, при наведении на имя персонажа, он будет показан в формате *имя персонажа*@*дескриптор*. На сайте, при входе под своим аккаунтом, Вы сможете увидеть дескриптор в верхней правой части страницы.
Рассмотрим, более детально, что значит дескриптор. Дескриптор (от латинского descriptor – описывающий) – это лексическая единица (словосочетание, слово) информационно-поискового языка, служит для того, чтобы описать основное смысловое содержание документа или формулировки запроса при поиске информации (документа) в информационно-поисковой системе. Дескриптор ставится однозначно в соответствие группе ключевых слов естественного языка, которые отобраны из текста, который относится к определенной области знаний. Таким образом, дескриптор можно смело считать самостоятельным языковым элементом.
Мы коротко рассмотрели дескриптор. Оставляйте свои комментарии или дополнения к материалу.
Руководство к дескрипторам
Краткий обзор
В этой статье я расскажу о том, что такое дескрипторы, о протоколе дескрипторов, покажу как вызываются дескрипторы. Опишу создание собственных и исследую несколько встроенных дескрипторов, включая функции, свойства, статические методы и методы класса. С помощью простого приложения покажу, как работает каждый из них, приведу эквиваленты внутренней реализации работы дескрипторов кодом на чистом питоне.
Изучение того, как работают дескрипторы, откроет доступ к большему числу рабочих инструментов, поможет лучше понять как работает питон, и ощутить элегантность его дизайна.
Введение и определения
Протокол дескрипторов
Собственно это всё. Определите любой из этих методов и объект будет считаться дескриптором, и сможет переопределять стандартное поведение, если его будут искать как атрибут.
Дескрипторы данных и не данных отличаются в том, как будет изменено поведение поиска, если в словаре объекта уже есть запись с таким же именем как у дескриптора. Если попадается дескриптор данных, то он вызывается раньше, чем запись из словаря объекта. Если в такой же ситуации окажется дескриптор не данных, то запись из словаря объекта имеет преимущество перед этим дескриптором.
Вызов дескрипторов
Пример дескриптора
Этот простой протокол предоставляет просто увлекательные возможности. Некоторые из них настолько часто используются, что были объединены в отдельные функции. Свойства, связанные и несвязанные методы, статические методы и методы класса — все они основаны на этом протоколе.
Свойства
Вызова property() достаточно, чтобы создать дескриптор данных, который вызывает нужные функции во время доступа к атрибуту. Вот его сигнатура:
В документации показано типичное использование property() для создания управляемого атрибута x :
Вот эквивалент property на чистом питоне, чтобы было понятно как реализовано property() с помощью протокола дескрипторов:
Встроенная реализация property() может помочь, когда существовал интерфейс доступа к атрибуту и произошли какие-то изменения, в результате которых понадобилось вмешательство метода.
Функции и методы
В питоне все объектно-ориентированные возможности реализованы с помощью функционального подхода. Это сделано совсем незаметно с помощью дескрипторов не данных.
С помощью интерпретатора мы можем увидеть как на самом деле работает дескриптор функции:
Вывод интерпретатора подсказывает нам, что связанные и несвязанные методы — это два разных типа. Даже если они могли бы быть реализованы таким образом, на самом деле, реализация PyMethod_Type в файле Objects/classobject.c содержит единственный объект с двумя различными отображениями, которые зависят только от того, есть ли в поле im_self значение или там содержится NULL (C эквивалент значения None ).
Статические методы и методы класса
Дескрипторы не данных предоставляют простой механизм для различных вариантов привязки функций к методам.
Так как staticmethod() возвращает функцию без изменений, то этот пример не удивляет:
Если использовать протокол дескриптора не данных, то на чистом питоне staticmethod() выглядел бы так:
В отличие от статических методов, методы класса подставляют в начало вызова функции ссылку на класс. Формат вызова всегда один и тот же, и не зависит от того, вызываем мы метод через объект или через класс.
Это поведение удобно, когда нашей функции всегда нужна ссылка на класс и ей не нужны данные. Один из способов использования classmethod() — это создание альтернативных конструкторов класса. В питоне 2.3, метод класса dict.fromkeys() создаёт новый словарь из списка ключей. Эквивалент на чистом питоне будет таким:
Теперь новый словарь уникальных ключей можно создать таким образом:
Если использовать протокол дескриптора не данных, то на чистом питоне classmethod() выглядел бы так:
Реализация понятия последовательного процесса в ОС (дескрипторы задач)
1. идентификатор процесса PID
2. тип (или класс) процесса, который определяет для супервизора некоторые правила для предоставления ресурса
3. приоритет процесса, в соответствии с которым супервизор предоставляет ресурсы. В рамках одного класса обслуживания в первую очередь обслуживаются более приоритетные процессы
4. переменную состояния процесса
5. защищенную область памяти (или ее адрес), в которой хранятся текущие значения регистров процессора, если процесс прерывается, не закончив работу. Эта информация называется контекстом задач
6. информация о ресурсах, которыми процесс владеет
7. место (или его адрес) для организации общения с другими процессами
8. параметры времени запуска (момент и периодичность)
Дескрипторы постоянно находятся в оперативной памяти в одном из списков (очередей).
Супервизор перемещает дескрипторы из одного списка в другой в зависимости от состояния процесса.
Для состояния ожидания обычно организуется столько списков, сколько имеется ресурсов, которые могут вызвать состояние ожидания.
Процессы и потоки
Понятие процесс было введено для реализации идеи мультипрограммирования.
Каждый процесс имеет свое виртуальное адресное пространство, имеет свои ресурсы (файлы, окна, семафоры), то есть обособляется друг от друга, чтобы защитить один процесс от другого, так как совместно используемые ресурсы вычислительной системы конкурируют друг с другом.
Но сами процессы можно разбить на ряд задач, которые могут выполняться параллельно. Такие подпроцессы называются потоками thread нитями.
Поток не имеет собственных ресурсов. Развивается в том же виртуальном адресном пространстве, что и другие потоки данного процесса. Потоки разделяют между собой процессорное время.
Многопоточность особенно эффективна для выполнения распределенных приложений.
При манипулировании потоками меняется только контекст задачи.
Каждый поток выполняется строго последовательно и имеет свой программный счетчик и стек. Потоки разделяют одни и те же глобальные перемены.
Между потоками нет полной защиты.
Для эффективной организации параллельной работы процессов и потоков в архитектуру современного процессора включена специальная возможность работы с дескрипторами. Для этого вводится понятие «задача» (task), которое объединяет в себе поток и процесс.
Дескриптор строится как для потоков, так и для процессов. Отличие заключается в том, что дескриптор потока хранит только контекст задач, которая приостановлена, а дескриптор процесса содержит дополнительные поля, описывающие ресурсы, выделенные этому процессу. Эта информация хранится в специальном регистре TSR.
Прерывание
Прерываниепредставляет собой механизм, позволяющий координировать параллельное функционирование отдельных устройств вычислительной системы и реагировать на особые состояния, возникающие при работе процессора.
Т.о. прерывание – это принудительная передача управления от выполняемой программы к системе (а через нее к программе обработки прерывания), происходящая при возникновении определенного события.
Идея прерываний была предложена в середине 50-х годов. Прерывание было создано для реализации асинхронного режима работы и распараллеливания работы отдельных устройств вычислительной системы.
Механизм прерывания реализуется аппаратно-программными средствами. В разных архитектурах прерывание непременно влечет за собой изменение порядка выполнения команд процессором.
Механизм обработки прерываний независимо от архитектуры вычислительной системы включает следующие элементы:
1. установление факта прерывания (прием сигнала и идентификация прерывания)
2. запоминание состояния прерванного процесса (счетчик команд, содержание регистров и т.д.).
3. управление аппаратно передается подпрограмме обработки прерывания. В счетчик команд заносится адрес первой команды подпрограммы обработки прерывания.
4. Сохранение информации о прерванной программе, которую не удалось спасти на втором шаге с помощью действий аппаратуры.
5. Обработка прерывания
6. Восстановление информации относящейся к прерванному процессу (шаг, противоположный 4-му)
7. Возврат в прерванную программу.
Шаги 1-3 реализуется аппаратно, а шаги 4-7- программно.
Главные функции:
1. Распознавание или классификация прерывания.
2. Передача управления соответствующему обработчику прерывания
3. Корректное возвращение к прерванной программе
Для быстрого перехода от прерывания к обработчику и обратно используется таблица, содержащая перечень всех допустимых для компьютера прерываний и адреса соответствующего обработчика.
2. От внешнего устройства ввода/вывода
3. При нарушении питания
4. С пульта оператора
5. От другого процесса или другой вычислительной системы
Внутреннее прерывание связано с работой процессора, например
1. при нарушении адресации,
2. При наличии в поле кода операции, не задействованной двоичной комбинации
3. при делении на ноль,
4. При переполнении или исчезновении порядка
5. При обнаружении ошибок четности и ошибок в работе различных устройств
Иногда выделяют прерывание, обращенное к супервизору ОС.
Существует собственно программное прерывание, которое происходит по соответствующей команде в программе.
При одновременном возникновении нескольких прерываний выбор одного из них осуществляется на основе приоритетов, предписанных каждому прерыванию.
В порядке убывания приоритета:
1. Средство контроля процессора
2. Системный таймер
3. Прерывание от внешнего устройства (магнитные диски, сетевое оборудование, терминалы)
4. программные прерывания.
Учет приоритета может быть реализован аппаратно или программно с применением различных дисциплин обслуживания прерывания.
Наличие сигнала прерывания не обязательно должно прерывать исполнение программ. Для этого созданы средства защиты прерывания:
1. Отключение системы прерывания полностью
2. Маскировка\запрет отдельных сигналов прерывания
Операции прерывания обычно выполняются только после завершения текущей команды.
Программное управление специальными регистрами (масками) позволяет реализовать различные дисциплины обслуживания.
1. с относительными приоритетами, т.н. обслуживание не прерывается, даже при наличии запроса с более высоким приоритетом. После обслуживания запроса, обслуживается запрос с наивысшим приоритетом. Маска накладывается на все основные сигналы прерывание или отключается система прерывания.
2. с абсолютными приоритетами, т.е. всегда обслуживается прерывание с высшим приоритетом. На время обработки прерывания маскируются прерывания более низкого приоритета.
3. по принципу стека (первый пришел – последний вышел), т.е. запросы с более низким приоритетом могут прервать обработку прерывания с более высоким приоритетом. Для этого, не накладываются маски и не отключается система прерывания.
В современных ОС причины прерывания определяет ОС (супервизор прерываний) и выполняет действия, необходимые при данном прерывании и в данной ситуации.
Супервизор прерываний сохраняет в дескрипторе текущей задачи значения рабочих регистров процессора, определяющие контекст прерываемого вычислительного процесса. Далее он определяет ту подпрограмму, которая должна выполнить действия, связанные с обслуживанием текущего запроса на прерывание, устанавливает необходимый режим обработки прерывания. После выполнения подпрограммы обработки прерывания управление передается супервизором на тот модуль, который занимается диспетчеризацией задач. И уже диспетчер задач, в соответствии с принятым режимом, распределяет процессорное время между выполняемыми процессами, восстанавливает контекст той задачи, которой будет решено выделить процессорное время. Т.о. нет непосредственного возврата в прерванную ранее программу прямо из самой подпрограммы обработки прерывания.
Преодолевая границы Windows: дескрипторы
Это уже пятая статья из моей серии публикаций «Преодолевая границы Windows», в которых я рассказываю о максимальном значении и объеме ресурсов, которыми управляет Windows, таких как физическая память, виртуальная память, процессы и потоки:
В большинстве случаев эти ограничения для дескрипторов находятся далеко от тех значений, которые обычно используются приложениями или системой. Однако, приложения, при разработке которых не учитывались эти ограничения, могут достигнуть их неожиданными для разработчиков путями. Чаще всего подобные проблемы возникают из-за того, что срок жизни этого вида ресурсов должен управляться приложениями, и, как в случае с виртуальной памятью, задача управления сроком жизни ресурсов является своего рода вызовом даже для самых лучших разработчиков. Приложение, которое не в состоянии освобождать неиспользуемые ресурсы, вызывает их утечку, что, в конечном счете, может привести к тому, что предел использования ресурса будет достигнут, приводя к странному и трудно диагностируемому поведению как данного, так и других приложений, или же всей системы в целом.
Как обычно, я рекомендую вам прочитать мои предыдущие публикации, поскольку в них объясняются некоторые из понятий, используемых в данной статье (например, выгружаемый пул).
Дескрипторы и объекты
Ядро Windows, работающее в привилегированном режиме, реализованное в образе %SystemRoot%\System32\Ntoskrnl.exe, состоит из различных подсистем, таких как диспетчер памяти, диспетчер процессов, диспетчер ввода/вывода, диспетчер конфигураций (системный реестр), которые является частями исполнительной системы. Каждая из этих подсистем вместе с диспетчером объектов определяет один или более типов для представления ресурсов, которые они выделяют приложениям. Например, диспетчер конфигураций определяет объект «ключ» (Key) для представления открытого ключа системного реестра; диспетчер памяти объект «Секция» (Section) для общей памяти; исполнительная система определяет объекты «семафор» (Semaphore), «мутант» (Mutant, внутреннее название для мьютекса) и «синхронизация событий» (Event synchronization) (эти объекты представляют собой оболочку для структур данных, определенных подсистемой Ядро операционной системы); диспетчер ввода/вывода определяет объект «файл» (File) для представления открытых экземпляров ресурсов драйверов устройств, которые включают в себя файлы файловой системы; и, наконец, диспетчер процессов создает объекты «поток» (Thread) и «процесс» (Process), о которых я рассказывал в своей последней публикации из данной серии. Каждый релиз Windows вводит новые типы объектов, в том числе и Windows 7, которые принес с собой в общей сложности 42 новых типа. Определенный в вашей системы объекты вы можете увидеть при помощи утилиты Winobj от Sysinternals, запущенной с правами администратора, открыв директорию ObjectTypes пространства имен Object Manager:
Когда приложение желает получить управление над одним из этих ресурсов, оно сначала должно вызвать соответствующий API, чтобы создать или открыть ресурс. Например, функция CreateFile открывает или создает файл, функция RegOpenKeyEx открывает ключ реестра, а функция CreateSemaporeEx открывает или создает семафор. Если такая функция успешно выполняется, Windows размещает дескриптор в таблице дескрипторов процесса приложения и возвращает значение этого дескриптора, которое приложение обрабатывает неявно, однако фактически речь идет об индексе возвращенного дескриптора в таблице дескрипторов.
Если бы этот процесс попытался бы что-то записать в файл, то функция завершила выполнение с ошибкой, поскольку подобный вид доступа к файлу не был предоставлен, а факт кэширования доступа на чтение означает, что система не должна снова повторять более затратную в плане ресурсов проверку прав доступа.
Этот результат, однако, не отображает общее количество дескрипторов, которые может создать процесс, поскольку системные библиотеки DLL открывают различные объекты во время инициализации процесса. Общее число дескрипторов процесса вы можете увидеть, добавив соответствующую колонку в диспетчере задач или Process Explorer. Общее цифра для Testlimit в данном случае равна 16’771’680:
Когда вы запускаете Testlimit на 32-битной системе, число дескрипторов будет немного отличаться:
Общее число дескрипторов также другое, 16’744’448:
Чем обуславливаются эти различия? Ответ состоит в том, что исполнительная система, ответственная за управление таблицей дескрипторов, устанавливает ограничение на количество дескрипторов для каждого процесса, а также на размер записи в таблице дескрипторов. Здесь мы имеем дело с одним из тех редких случаев, когда Windows устанавливает жесткое ограничение на использование ресурса, так что в данном случае исполнительная система определяет число 16’777’216 (16*1024*1024) как максимальное количество дескрипторов, которое может быть выделено процессу. Любой процесс, которые имеет более десяти тысяч дескрипторов одновременно в какой-либо момент времени, весьма вероятно имеет либо серьезные недочеты, допущенные при его проектировании, или утечку дескрипторов. Так что предел в 16 миллионов дескрипторов практически недостижим и призван помочь предотвратить утечку памяти, вызванную вмешательством в работу процесса со стороны остальной системы. Чтобы понять причину того, почему число, отображаемое в диспетчере задач, отличается от жестко установленного максимума, требуется рассмотреть то, каким образом исполнительная система организовывает таблицу дескрипторов.
Запись таблицы дескрипторов должна иметь достаточный размер для того, чтобы хранить маску прав доступа и указатель на объект. Маска доступа является 32-битной, но размер указателя, очевидно, зависит от того, является система 32-битной или 64-битной. Следовательно, запись дескриптора занимает 8 байт на 32-битной Windows и 12-байт на 64-битной Windows. 64-битная Windows дополняет структуры данных записи дескриптора до 64-битных границ, так что 64-битная запись дескриптора фактически занимает 16 байт. Вот определение записи дескрипторов на 64-битной Windows, отображенное в отладчике ядра с помощью команды dt (dump type):
Здесь мы видим, что данная структура содержит в себе и другую информацию, помимо указателя на объект и маски доступа, выделенных на скриншоте.
Дескрипторы и выгружаемый пул
Вторым ограничением, касающимся дескрипторов, является объем памяти, требуемой для хранения таблицы дескрипторов, который исполнительная система выделяет из выгружаемого пула. Исполнительная система для отслеживания выделяемых ею под таблицы дескрипторов страниц использует трехуровневую схему, подобную той, которую используют модули управления памятью (MMU) процессора для руководства трансляциями виртуальных адресов в физические. Мы уже рассматривали с вами организацию нижнего и среднего уровней, которые фактически хранят в себе записи таблицы дескрипторов. Верхний уровень служит в качестве указателей на таблицы среднего уровня и включает в себя 1024 записи на страницу в 32-битной Windows. Отсюда следует, что общее количество страниц, требуемых для хранения максимального числа дескрипторов для 32-битной Windows можно вычислить как 16’777’216/512*4096, что равно 128 Мб. Это совпадает с показателями использования Testlimit выгружаемого пула, которые показывает диспетчер задач:
В 64-битной версии Windows на верхнем уровне содержится 256 указателей на страницу. Это означает в общем для размещения полной таблицы дескрипторов используется 256 Мб выгружаемого пула (16’777’216/256*4096). Правильность данных вычислений подтверждается показателями использования Testlimit выгружаемого пула на 64-битной Windows:
Объема выгружаемого пула более чем достаточно, чтобы сохранить эти структуры данных, однако, как я уже говорил ранее, процесс, который создает слишком много дескрипторов, почти наверняка исчерпает какой-то другой ресурс, и, если он достигнет ограничения на количество дескрипторов для одного процесса, то ему не удастся открыть никакие другие объекты.
По умолчанию Process Explorer показывает только дескрипторы, которые указывают на объекты, имеющие имена, что означает, что вы не увидите всех дескрипторов процесса, если не включите опцию «Show Unnamed Handles and Mappings» в меню View. Вот некоторые безымянные дескрипторы из таблицы дескрипторов командной строки:
Как и в случае с большинством других ошибок, только разработчик кода, из-за которого происходит утечка, может исправить это. Если вы обнаружили утечку у процесса, который состоит из нескольких компонентов или расширений, например, Explorer, Service Host или Internet Explorer, то главный вопрос состоит в том, какая из этих частей ответственна за утечку. Определение такого компонента позволило бы вам избежать появления проблемы, отключив или удалив проблемное расширение, проверить его на наличие обновлений, исправляющих эту ошибку или сообщить о ней разработчику.
Прекрасным источником советов о том, как можно устранить утечки дескрипторов является интервью инженера по технической поддержке Microsoft Джеффа Дэйли (Jeff Dailey) для Channel 9.
В следующий раз я рассмотрю ограничения, установленные для таких основанных на дескрипторах ресурсов, как объекты GDI и USER. Дескрипторы этих ресурсов управляются подсистемой Windows, отличной от исполнительной системы, а потому используют другие ресурсы и имеют другие ограничения.