«Почему нет нечетных идентификаторов процессов Windows?"
Тот же код, который выделяет дескрипторы ядра, также используется для выделения идентификаторов процессов и потоков. Так как дескрипторы ядра кратны четырем, то же самое происходит с идентификаторами процессов и потоков.
Почему идентификаторы процессов и потоков кратны четырем?
В операционных системах на базе Windows NT идентификаторы процессов и потоков всегда кратны четырем. Это просто совпадение?
Да, это просто совпадение, и вы не должны полагаться на него, поскольку это не является частью контракта на программирование. Например, идентификаторы процессов и потоков в Windows 95 не всегда были кратны четырем. (Для сравнения, причина, по которой дескрипторы ядра всегда кратны четырем, является частью спецификации и будет гарантирована в обозримом будущем.)
Идентификаторы процессов и потоков кратны четырем, что является побочным эффектом повторного использования кода. Тот же код, который выделяет дескрипторы ядра, также используется для выделения идентификаторов процессов и потоков. Так как дескрипторы ядра кратны четырем, то же самое происходит с идентификаторами процессов и потоков. Это деталь реализации, поэтому не пишите код, который опирается на него. Я просто говорю вам, чтобы удовлетворить ваше любопытство.
Источник Почему идентификаторы процессов и потоков кратны четырем?
Почему РУЧКИ ядра всегда кратны четырем?
Не очень хорошо известно, что нижние два бита РУЧКИ ядра всегда равны нулю; другими словами, их числовое значение всегда кратно 4. Обратите внимание, что это относится только к РУЧКАМ ядра; это не относится к псевдо-дескрипторам или к любому другому типу дескрипторов (дескрипторы USER, дескрипторы GDI, мультимедийные дескрипторы ...) Дескрипторы ядра - это то, что вы можете передать функции CloseHandle.
Наличие двух нижних битов скрыто в заголовочном файле ntdef.h:
//
// Low order two bits of a handle are ignored by the system and available
// for use by application code as tag bits. The remaining bits are opaque
// and used to store a serial number and table index.
//
#define OBJ_HANDLE_TAGBITS 0x00000003L
То, что по крайней мере нижний бит ядра HANDLE всегда равен нулю, подразумевается функцией GetQueuedCompletionStatus, которая указывает, что вы можете установить нижний бит дескриптора события, чтобы подавить уведомление порта завершения. Чтобы это работало, нижний бит обычно должен быть нулевым.
Эта информация бесполезна для большинства разработчиков приложений, которые должны продолжать обрабатывать HANDLE как непрозрачные значения. Люди, которые будут заинтересованы в битах тегов, это те, кто реализует низкоуровневые библиотеки классов или оборачивает объекты ядра в более крупную структуру.
Источник Почему РУЧКИ ядра всегда кратны четырем?
дальнейшее чтение