Objetos de trabalho

Um objeto de trabalho permite que grupos de processos sejam gerenciados como uma unidade. Objetos de trabalho são objetos navegáveis, protegíveis e fragmentáveis que controlam atributos dos processos associados a eles. As operações realizadas em um objeto de trabalho afetam todos os processos associados ao objeto de trabalho. Os exemplos incluem impor limites como tamanho do conjunto de trabalho e prioridade do processo ou encerrar todos os processos associados a um trabalho.

Criando trabalhos

Para criar um objeto de trabalho, use a função CreateJobObject . Quando o trabalho é criado, nenhum processo é associado ao trabalho.

Para associar um processo a um trabalho, use a função AssignProcessToJobObject . Depois que um processo é associado a um trabalho, a associação não pode ser interrompida. Um processo pode ser associado a mais de um trabalho em uma hierarquia de trabalhos aninhados. Para obter mais informações, consulte Trabalhos Aninhados.

Windows 7, Windows Server 2008 R2, Windows XP com SP3, Windows Server 2008, Windows Vista e Windows Server 2003: Um processo pode ser associado a apenas um trabalho. Os trabalhos não podem ser aninhados. A capacidade de aninhar trabalhos foi adicionada em Windows 8 e Windows Server 2012.

Você pode especificar um descritor de segurança para um objeto de trabalho ao chamar a função CreateJobObject . Para obter mais informações, consulte Segurança do objeto de trabalho e direitos de acesso.

Gerenciando processos em trabalhos

Depois que um processo é associado a um trabalho, por padrão, todos os processos filho que ele cria usando CreateProcess também são associados ao trabalho. (Os processos filho criados usando Win32_Process.Create não estão associados ao trabalho.) Esse comportamento padrão pode ser alterado definindo o limite estendido JOB_OBJECT_LIMIT_BREAKAWAY_OK ou JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK para o trabalho.

  • Se o trabalho tiver o limite estendido JOB_OBJECT_LIMIT_BREAKAWAY_OK e o processo pai tiver sido criado com o sinalizador CREATE_BREAKAWAY_FROM_JOB, os processos filho do processo pai não serão associados ao trabalho.
  • Se o trabalho tiver o limite estendido JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK, os processos filho de qualquer processo pai associado ao trabalho não serão associados ao trabalho. Não é necessário que os processos pai sejam criados com o sinalizador CREATE_BREAKAWAY_FROM_JOB.

Se o trabalho estiver aninhado, as configurações de separação de trabalhos pai na hierarquia afetarão se os processos filho estão associados a outro trabalho na hierarquia. Para obter mais informações, consulte Trabalhos Aninhados.

Para determinar se um processo está em execução em um trabalho, use a função IsProcessInJob .

Para encerrar todos os processos atualmente associados a um objeto de trabalho, use a função TerminateJobObject .

Limites e notificações de trabalho

Um trabalho pode impor limites como tamanho do conjunto de trabalho, prioridade do processo e limite de tempo de fim do trabalho em cada processo associado ao trabalho. Se um processo associado a um trabalho tentar aumentar o tamanho do conjunto de trabalho ou a prioridade do processo do limite estabelecido pelo trabalho, as chamadas de função serão bem-sucedidas, mas serão silenciosamente ignoradas. Um trabalho também pode definir limites que disparam uma notificação quando elas são excedidas, mas permitem que o trabalho continue a ser executado.

Para definir limites para um trabalho, use a função SetInformationJobObject . Para obter uma lista de possíveis limites que podem ser definidos para um trabalho, consulte os seguintes tópicos:

Os limites de segurança devem ser definidos individualmente para cada processo associado a um objeto de trabalho. Para obter mais informações, consulte Direitos de Acesso e Segurança do Processo.

Windows XP com SP3 e Windows Server 2003: A função SetInformationJobObject pode ser usada para definir limitações de segurança para todos os processos associados a um objeto de trabalho. A partir do Windows Vista, os limites de segurança devem ser definidos individualmente para cada processo associado a um objeto de trabalho.

Se o trabalho estiver aninhado, os trabalhos pai na hierarquia influenciarão o limite imposto para o trabalho. Para obter mais informações, consulte Trabalhos Aninhados.

Se o trabalho tiver uma porta de conclusão de E/S associada, ele poderá receber notificações quando determinados limites de trabalho forem excedidos. O sistema envia mensagens para a porta de conclusão quando um limite é excedido ou ocorrem determinados outros eventos. Para associar uma porta de conclusão a um trabalho, use a função SetInformationJobObject com a classe de informações do objeto de trabalho JobObjectAssociateCompletionPortInformation e um ponteiro para uma estrutura JOBOBJECT_ASSOCIATE_COMPLETION_PORT . É melhor fazer isso quando o trabalho está inativo, para reduzir a chance de notificações ausentes para processos cujos estados mudam durante a associação da porta de conclusão.

Todas as mensagens são enviadas diretamente do trabalho como se o trabalho tivesse chamado a função PostQueuedCompletionStatus . Um thread deve monitorar a porta de conclusão usando a função GetQueuedCompletionStatus para pegar as mensagens. Observe que, com exceção dos limites definidos com a classe de informações JobObjectNotificationLimitInformation , a entrega de mensagens para a porta de conclusão não é garantida; A falha de uma mensagem para chegar não significa necessariamente que o evento não ocorreu. As notificações para limites definidos com JobObjectNotificationLimitInformation têm a garantia de chegar à porta de conclusão. Para obter uma lista de possíveis mensagens, consulte JOBOBJECT_ASSOCIATE_COMPLETION_PORT.

Contabilidade de recursos para trabalhos

O objeto de trabalho registra informações básicas de contabilidade para todos os seus processos associados, incluindo aqueles que foram encerrados. Para recuperar essas informações contábeis, use a função QueryInformationJobObject . Para obter uma lista das informações contábeis mantidas para um trabalho, consulte os seguintes tópicos:

Se o objeto de trabalho estiver aninhado, as informações contábeis de cada trabalho filho serão agregadas em seu trabalho pai. Para obter mais informações, consulte Trabalhos Aninhados.

Gerenciando objetos de trabalho

O estado de um objeto de trabalho é definido como sinalizado quando todos os seus processos são encerrados porque o limite de tempo de fim do trabalho especificado foi excedido. Use WaitForSingleObject ou WaitForSingleObjectEx para monitorar o objeto de trabalho desse evento.

Para obter um identificador para um objeto de trabalho existente, use a função OpenJobObject e especifique o nome fornecido ao objeto quando ele foi criado. Somente objetos de trabalho nomeados podem ser abertos.

Para fechar um identificador de objeto de trabalho, use a função CloseHandle . O trabalho é destruído quando seu último identificador foi fechado e todos os processos associados foram encerrados. No entanto, se o trabalho tiver o sinalizador JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE especificado, fechar o último identificador de objeto de trabalho encerrará todos os processos associados e destruirá o próprio objeto de trabalho. Se um trabalho aninhado tiver o sinalizador JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE especificado, fechar o último identificador de objeto de trabalho encerrará todos os processos associados ao trabalho e seus trabalhos filho na hierarquia.

Gerenciando uma árvore de processo que usa objetos de trabalho

Começando com Windows 8 e Windows Server 2012, um aplicativo pode usar trabalhos aninhados para gerenciar uma árvore de processo que usa mais de um objeto de trabalho. No entanto, um aplicativo que deve ser executado no Windows 7, Windows Server 2008 R2 ou versões anteriores do Windows que não dão suporte a trabalhos aninhados deve gerenciar a árvore de processo de outras maneiras.

Se uma ferramenta precisar gerenciar uma árvore de processo que usa objetos de trabalho e não for possível usar trabalhos aninhados, a ferramenta e os membros da árvore de processo deverão cooperar. Use uma das seguintes opções:

  • Use o limite de JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK. Se a ferramenta usar esse limite, ela não poderá monitorar uma árvore de processo inteira. A ferramenta pode monitorar apenas os processos que adiciona ao trabalho. Se esses processos criarem processos filho, eles não serão associados ao trabalho. Nessa opção, os processos filho podem ser associados a outros objetos de trabalho.

  • Use o limite de JOB_OBJECT_LIMIT_BREAKAWAY_OK. Se a ferramenta usar esse limite, ela poderá monitorar toda a árvore de processo, exceto pelos processos que qualquer membro da árvore se separa explicitamente da árvore. Um membro da árvore pode criar um processo filho em um novo objeto de trabalho chamando a função CreateProcess com o sinalizador CREATE_BREAKAWAY_FROM_JOB e chamando a função AssignProcessToJobObject . Caso contrário, o membro deve lidar com casos em que AssignProcessToJobObject falha.

    O sinalizador CREATE_BREAKAWAY_FROM_JOB não terá efeito se a árvore não estiver sendo monitorada pela ferramenta. Portanto, essa é a opção preferencial, mas requer conhecimento avançado dos processos que estão sendo monitorados.

  • Evite separações de qualquer tipo definindo nem o JOB_OBJECT_LIMIT_BREAKAWAY_OK nem o limite de JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK. Nessa opção, a ferramenta pode monitorar toda a árvore de processo. No entanto, se um processo filho tentar associar a si mesmo ou a outro processo filho a um trabalho chamando AssignProcessToJobObject, a chamada falhará. Se o processo foi projetado para ser associado a um trabalho específico, essa falha poderá impedir que o processo funcione corretamente.