DuplicateHandle (), utilização em primeiro ou segundo processo?
Pergunta
A API do Windows DuplicateHandle () http://msdn.microsoft.com/en-us /library/ms724251(VS.85).aspx Requer o identificador de objeto a ser duplicado e um identificador para tanto o processo original e o outro processo que você deseja utilizar a alça duplicada em.
Estou assumindo que se eu tiver dois processos não relacionados, eu poderia chamar DuplicateHandle () em qualquer um, desde que eu tinha as alças necessários estão disponíveis?
A minha pergunta é sobre o uso de um tubo para se comunicar entre os dois processos para conseguir isso com um evento.
No primeiro processo I CreateEvent (). Agora eu quero usar WaitForSingleObject () no segundo processo.
Se eu tentar duplicar o punho no primeiro processo, precisa primeiro enviar o segundo identificador de processo para o primeiro processo através do tubo, duplicar o cabo e, em seguida, enviar o identificador para o segundo processo?
Alternativly, eu poderia começar enviando o primeiro identificador de processo eo identificador de evento para o segundo processo e apenas duplicá-lo lá.
Existe uma razão pela qual eu deveria escolher um sobre o outro?
Para adicionar uma ruga, a alça de eventos é realmente herdada do processo pai que realmente chamado o primeiro processo (que é uma aplicação CGI). Se esse identificador de evento foi criado com HANDLE_DO_NOT_DUPLICATE (algo assim), então pode I em uso fato DuplicateHandle () para duplicá-lo para o segundo processo?
Resposta:
Bem, eu poderia criar um novo evento nomeado no primeiro processo e encontrá-lo no segundo processo, tal como sugerido, mas estou tentando duplicar o evento que foi criado no pai do primeiro processo e foreward-lo para o segundo processo . Este evento não é um evento chamado assim eu preciso usar DuplicateHandle ().
Eu estou usando um tubo para o IPC. Estou percebendo que DuplicateHandle () terá que ser chamado no primeiro processo, porque o identificador de eventos está fora de contexto, quando enviado para o segundo processo.
hProcPseudo = GetCurrentProcess()
//Then call either:
lpRealHandle = OpenProcess( PROCESS_DUP_HANDLE, 0, hProcPseudo )
//This fails with GetLastError= 87 - The parameter is incorrect ???
// same thing with PROCESS_ALL_ACCESS ??
//OR
lRet = DuplicateHandle( hProcPseudo, hProcPseudo, hProcPseudo, lpRealHandle, DUPLICATE_SAME_ACCESS, 0, 0 )
//then I can Duplicate my Event Handle in the first thread with:
lRet = DuplicateHandle( hLocalProcess, hEvent, lpRealHandle, hDupEvent, DUPLICATE_SAME_ACCESS, 0, 0)
O segundo processo converte o seu punho com DuplicateHandle () detalhado acima convertendo
hProcPseudo = 4294967295
para
hProcess = 152
Então eu passar este identificador de processo para o primeiro processo por meio do pipe nomeado. No primeiro processo (onde o identificador de evento é válido) eu chamo alça duplicado:
DuplicateHandle( hFirstProcess, hEvent, hSecondProc, hDupEvent, DUPLICATE_SAME_ACCESS, 0, 0)
Infelizmente eu recebo o erro:
DuplicateHandle hPipeFCGI GetLastError = 6 - O identificador é inválido.
Mais testes (substituindo hFirstProcess) revela que é hSecondProc que é inválido! ??
Big Mistério.
Solução
Use a chamado tubo ou < a href = "http://msdn.microsoft.com/en-us/library/aa365576(VS.85).aspx" rel = "nofollow noreferrer"> mailslots para IPC, isso deve funcionar de forma confiável para o seu objetivo. Se você precisa esperar, o uso alças de espera nomeado.
Caso contrário, eu escolheria para fazer DuplicateHandle no segundo processo, a fim de definir a propriedade punho corretamente.
Outras dicas
identificador de processo é diferente do ID do processo. OpenProcess leva id processo. Use algo como ...
= PUNHO hProcess OpenProcess (PROCESS_DUP_HANDLE, FALSO, GetCurrentProcessId ());
Se bem entendi, você deseja sincronizar dois processos não relacionados através do mesmo evento. Se assim for, você pode usar eventos nomeados.
Criar um usando a função API CreateEvent , fornecer-lhe um nome, em seguida, a partir do segundo processo o uso OpenEvent função API , especificando o nome do evento.
Você tem funções semelhantes para outros objetos de sincronização, tais como semáforos ( OpenMutex ) ou semáforos ( OpenSemaphore ) .
- De alguma forma, o segundo processo precisa para obter o seu ID do processo para o primeiro processo. Isto pode ser obtido através
GetCurrentProcessId()
- O primeiro processo agora precisa usar este ID para obter um
HANDLE
ao segundo processo:hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwProcessId);
- Agora você pode duplicar o punho no primeiro processo, usando a alça REAIS processo do segundo processo e o pseudo-handle do primeiro processo:
DuplicateHandle(GetCurrentProcess(), hEvent, hProcess, &hDupEvent, 0, FALSE, DUPLICATE_SAME_ACCESS);
- Lembre-se de soltar a alça que você criou com
OpenProcess
, eventualmente (não sei que diferença faria, mas você deveria ...). Além disso, solte as duas alças para o evento:. O dado para o segundo processo ea alça inicial