DuplicateHandle, почему дублировать, а не просто приобрести? - PullRequest
3 голосов
/ 31 января 2010

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

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

Ответы [ 4 ]

6 голосов
/ 31 января 2010

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

Чувство собственной идентичности
Иногда вам может потребоваться получить реальный дескриптор потока вместо псевдо-дескриптора. Под «реальным» я подразумеваю дескриптор, который однозначно идентифицирует уникальный поток. Изучите следующий код:
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 голос
/ 13 апреля 2016

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

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

1 голос
/ 31 января 2010

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

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

1 голос
/ 31 января 2010

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

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

...