2010-01-31 3 views
3

Почему процесс хотел бы вызвать DuplicateHandle из Win32API и получить его из другого процесса вместо того, чтобы просто получить дескриптор на каком-либо объекте?DuplicateHandle, зачем дублировать, а не просто приобретать?

Есть ли какое-то преимущество в вызове DuplicateHandle или что-то в этом роде?

+0

Я не уверен, что вы просите. – SLaks

+0

Зачем вам называть DuplicateHandle вместо того, чтобы просто получить дескриптор объекта, как обычно? –

ответ

5

Ответ на этот вопрос можно найти в главе 6.8 «Программирование приложений для Microsoft Windows».

Получение чувства собственного достоинства
Иногда вам может понадобиться приобрести реальную ручку для потока вместо псевдо-ручка. Под «real» подразумевается дескриптор, который однозначно идентифицирует уникальный поток. Рассмотрим следующий код:
DWORD WINAPI ParentThread(PVOID pvParam) { 
    HANDLE hThreadParent = GetCurrentThread(); 
    CreateThread(NULL, 0, ChildThread, (PVOID) hThreadParent, 0, NULL); 
    // Function continues... 
} 

DWORD WINAPI ChildThread(PVOID pvParam) { 
    HANDLE hThreadParent = (HANDLE) pvParam; 
    FILETIME ftCreationTime, ftExitTime, ftKernelTime, ftUserTime; 
    GetThreadTimes(hThreadParent, 
     &ftCreationTime, &ftExitTime, &ftKernelTime, &ftUserTime); 
    // Function continues... 
} 
Вы можете увидеть проблему с этим фрагментом кода? Идея состоит в том, чтобы родительский поток передавал дочернему потоку описатель потока, который идентифицирует родительский поток. Тем не менее, родительский поток передает псевдо-дескриптор, а не реальный дескриптор. Когда дочерний поток начинает выполняться, он передает псевдо-дескриптор функции GetThreadTimes, которая заставляет дочерний поток получать свои собственные времена процессора, а не процессорные времена родительского потока. Это происходит потому, что псевдо-дескриптор потока является дескриптором текущего потока, то есть дескриптором того, какой поток выполняет вызов функции.

Чтобы исправить этот код, мы должны превратить псевдо-ручку в настоящий дескриптор. Функция DuplicateHandle (обсуждается в главе 3), могут сделать это преобразование
1

См. Здесь, в MSDN, что он должен сказать об использовании 'DuplicateHandle'. Лучший способ, которым я могу думать об этом, - это аналогия, если хотите - предположим, что вы открываете файл, используя процедуру CreateHandle для записи только, тогда вы вызываете DuplicateHandle, чтобы передать дескриптор на другой поток, в котором поток будет читать из файл, только ручка дублируется, поэтому поток не нужно сновазывать CreateHandle ...

Надеюсь, это поможет, С уважением, Tom.

1

Одним из возможных вариантов использования DuplicateHandle является дублирование дескриптора между 32-разрядным процессом и 64-разрядным процессом.

Примечание: не может использоваться для портов ввода-вывода ввода-вывода или гнезд.

1

Другое использование DuplicateHandle, чтобы открыть файл в нескольких процессах, когда файл использует FileOptions.DeleteOnClose. (Такой файл не может быть открыт несколькими процессами, если путь к файлу используется для открытия файла)

Смотрите мой ответ на https://stackoverflow.com/a/36606283/2221472