Rodrigo Strauss :: Blog
Win32: Processo
Um processo é, simplificadamente, uma instância de um programa que está sendo executado em um determinado momento. Por exemplo, quando abrimos três instâncias do Bloco de Notas, temos três processos independentes.

Vale lembrar que apesar de ser comum o termo "executar" um processo, o que executa não é o processo, e sim uma ou mais threads que fazem parte desse processo (mais sobre threads depois).
No exemplo acima vimos que 3 instâncias do Bloco de Notas são três processos diferentes, que têm em comum o fato do código executável ser carregado do mesmo arquivo, o notepad.exe. Um processo é um container para diversas estruturas, entre elas:
- Espaço de endereçamento de memória. Cada processo tem seu espaço de endereçamento isolado.
- Handles de arquivos, sockets, dispositivos, chaves de registros, etc.
- Tokens de segurança e accesso
- Threads, que são as linhas de execução que rodam o código do processo. Todo processo é constituído de uma ou mais threads, criadas pelo próprio processo ou por componentes do Windows.
Em Win32, a função usada para criar processos é a (surpresa!) CreateProcess:
#include <windows.h> #include <stdio.h> void main() { STARTUPINFO si; PROCESS_INFORMATION p; // // dica: muitas estruturas no Windows têm uma variável membro chamada // cb ou cbSize. Esse membro deve ser preenchido com o sizeof() // da estrutura ANTES de chamar a função. Se você não fizer isso a função // retornará um erro. Esse é um erro comum de iniciantes (eu apanhei muito...) // ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&p, sizeof(p)); // // Abrindo o Bloco de Notas // if(CreateProcess( NULL, // Sem módulo "C:\\WINDOWS\\notepad.exe", // linha de comando para o executável NULL, NULL, FALSE, // O processo criado não herdará os handles 0, NULL, NULL, &si, // Ponteiro para STARTUPINFO &p ) == FALSE) // Ponteiro para PROCESS_INFORMATION { printf( "Erro em CreateProcess: 0x%X", GetLastError() ); return; } // // O CreateProcess preencheu as estruturas e colocou handles nelas // como não vamos usar os handles, precisamos fechá-los... // CloseHandle(p.hProcess); CloseHandle(p.hThread); }
Sobre preencher o membro cb com o sizeof da estrutura, isso é usado para versionamento. Afinal, quando uma versão nova do Windows precisa de mais parâmetros para uma função, ao invés de criar uma nova versão (isso é C, não existe overload), mais membros são adicionados à estrutura, aumentando seu tamanho.
Esse foi um pequeno trecho de código, mas de bom tamanho para quem está começando com Win32, e é bom para entender como as coisas funcionam. Além disso, pretendo manter os posts pequenos para facilitar a leitura de todos, afinal, eu não sou o único aqui que tem um software para fazer...
Em 27/01/2008 04:38, por Rodrigo Strauss





Uma outra dica, que acostumei-me a usar por praticidade (e por usar apenas uma linha de código!) é inicializar as estruturas Windows direto da definição. Como o membro cbSize sempre é o primeiro, é possível inicializá-lo e deixar o resto zerado (obs: isso também funciona em ANSI C):
STARTUPINFO si = { sizeof(si) };
Obs. importante: até o Visual Studio 2003, a instrução assembly equivalente dessa inicialização era uma chamada direta da instrução que completa uma memória com o valor de um registrador. A partir do 2005 (não testei em 2008) qualquer inicialização desse estilo irá chamar a função da libc memset. Isso seria passado despercebido, se o mundo fosse perfeito e não existissem projetos onde somos proibicos de usar a libc por questões internas ou tamanho do código final, mesmo =)
[]s