mweerden: O NT foi projetado para vários usuários desde o primeiro dia, então esse não é realmente um motivo. No entanto, você está certo quanto ao fato de que a criação de processos desempenha um papel menos importante no NT do que no Unix, pois o NT, ao contrário do Unix, favorece o multithreading ao invés do multiprocessamento.
Rob, é verdade que fork é relativamente barato quando COW é usado, mas, na verdade, fork é geralmente seguido por um executivo. E um executivo deve carregar todas as imagens também. Discutir o desempenho do garfo, portanto, é apenas parte da verdade.
Ao discutir a velocidade de criação do processo, provavelmente é uma boa idéia distinguir entre NT e Windows / Win32. No que diz respeito ao NT (ou seja, o próprio kernel), não acho que a criação de processos (NtCreateProcess) e a criação de threads (NtCreateThread) seja significativamente mais lenta do que no Unix médio. Pode haver um pouco mais acontecendo, mas não vejo o motivo principal para a diferença de desempenho aqui.
Se você observar o Win32, entretanto, perceberá que ele adiciona um pouco de sobrecarga à criação do processo. Por um lado, requer que o CSRSS seja notificado sobre a criação do processo, que envolve o LPC. Ele exige que pelo menos o kernel32 seja carregado adicionalmente e precisa realizar vários itens de trabalho de contabilidade adicionais antes que o processo seja considerado um processo Win32 completo. E não nos esqueçamos de toda a sobrecarga adicional imposta pela análise de manifestos, verificando se a imagem requer um shim de compatibilidade, verificando se as políticas de restrição de software se aplicam, blá, blá.
Dito isso, vejo a desaceleração geral na soma de todas aquelas pequenas coisas que precisam ser feitas, além da criação bruta de um processo, espaço VA e thread inicial. Mas, como disse no início - devido ao favorecimento do multithreading em relação à multitarefa, o único software que é seriamente afetado por essa despesa adicional é o software Unix mal portado. Embora esta situação mude quando softwares como o Chrome e o IE8 de repente redescobrem os benefícios do multiprocessamento e começam a inicializar e desmontar com frequência os processos ...
O Unix tem uma chamada de sistema 'fork' que 'divide' o processo atual em dois e dá a você um segundo processo que é idêntico ao primeiro (módulo o retorno da chamada fork). Como o espaço de endereço do novo processo já está instalado e funcionando, isso deve ser mais barato do que chamar 'CreateProcess' no Windows e fazer com que carregue a imagem exe, dlls associados, etc.
No caso da bifurcação, o sistema operacional pode usar a semântica de 'cópia na gravação' para as páginas de memória associadas aos dois novos processos para garantir que cada um obtenha sua própria cópia das páginas que eles modificam subsequentemente.
fonte
Adicionando ao que JP disse: a maior parte da sobrecarga pertence à inicialização do Win32 para o processo.
O kernel do Windows NT realmente suporta bifurcação COW. SFU (ambiente UNIX da Microsoft para Windows) os utiliza. No entanto, o Win32 não oferece suporte a fork. Os processos SFU não são processos Win32. SFU é ortogonal ao Win32: ambos são subsistemas de ambiente construídos no mesmo kernel.
Além das chamadas LPC fora do processo para
CSRSS
, no XP e posterior, há uma chamada fora do processo para o mecanismo de compatibilidade de aplicativos para localizar o programa no banco de dados de compatibilidade de aplicativos. Esta etapa causa sobrecarga suficiente para que a Microsoft forneça uma opção de política de grupo para desabilitar o mecanismo de compatibilidade no WS2003 por motivos de desempenho.As bibliotecas de tempo de execução Win32 (kernel32.dll, etc.) também fazem muitas leituras de registro e inicialização na inicialização que não se aplicam a UNIX, SFU ou processos nativos.
Os processos nativos (sem subsistema de ambiente) são muito rápidos de criar. SFU faz muito menos do que Win32 para a criação de processos, portanto, seus processos também são rápidos de criar.
ATUALIZAÇÃO PARA 2019: adicionar LXSS: Subsistema Windows para Linux
Substituindo SFU para Windows 10 é o subsistema de ambiente LXSS. É 100% do modo kernel e não requer nenhum IPC que o Win32 continua a ter. Syscall para esses processos é direcionado diretamente para lxss.sys / lxcore.sys, portanto, o fork () ou outro processo de criação de chamada custa apenas 1 chamada de sistema para o criador, no total. [Uma área de dados chamada instância] mantém o controle de todos os processos LX, threads e estado de tempo de execução.
Os processos LXSS são baseados em processos nativos, não em processos Win32. Todas as coisas específicas do Win32, como o mecanismo de compatibilidade, não são acionadas.
fonte
Além da resposta de Rob Walker: Hoje em dia você tem coisas como a Native POSIX Thread Library - se quiser. Mas por muito tempo, a única maneira de "delegar" o trabalho no mundo unix era usar fork () (e ainda é preferido em muitas, muitas circunstâncias). por exemplo, algum tipo de servidor de socket
Portanto, a implementação do fork teve que ser rápida e muitas otimizações foram implementadas ao longo do tempo. A Microsoft endossou CreateThread ou mesmo fibras em vez de criar novos processos e uso de comunicação entre processos. Eu acho que não é "justo" comparar CreateProcess com fork, pois eles não são intercambiáveis. Provavelmente é mais apropriado comparar fork / exec com CreateProcess.fonte
A chave para essa questão é o uso histórico de ambos os sistemas, eu acho. O Windows (e o DOS antes disso) foram originalmente sistemas de usuário único para computadores pessoais . Como tal, esses sistemas normalmente não precisam criar muitos processos o tempo todo; (muito) simplesmente, um processo só é criado quando esse usuário solitário o solicita (e nós, humanos, não operamos muito rápido, relativamente falando).
Os sistemas baseados em Unix foram originalmente sistemas e servidores multiusuário. Especialmente para o último, não é incomum ter processos (por exemplo, mail ou daemons http) que separam processos para lidar com tarefas específicas (por exemplo, cuidar de uma conexão de entrada). Um fator importante para fazer isso é o
fork
método barato (que, como mencionado por Rob Walker ( 47865 ), usa inicialmente a mesma memória para o processo recém-criado), que é muito útil porque o novo processo tem imediatamente todas as informações de que precisa.É claro que, pelo menos historicamente, a necessidade de sistemas baseados em Unix para criação rápida de processos é muito maior do que para sistemas Windows. Acho que ainda é o caso porque os sistemas baseados em Unix ainda são muito orientados a processos, enquanto o Windows, devido à sua história, provavelmente foi mais orientado a threads (threads sendo úteis para fazer aplicativos responsivos).
Isenção de responsabilidade: eu não sou de forma alguma um especialista neste assunto, então me perdoe se eu entendi errado.
fonte
Uh, parece haver um monte de justificativa do tipo "é melhor assim".
Acho que as pessoas poderiam se beneficiar lendo "Showstopper"; o livro sobre o desenvolvimento do Windows NT.
O motivo pelo qual os serviços são executados como DLLs em um processo no Windows NT é que eles eram lentos demais como processos separados.
Se você se complicar, descobrirá que a estratégia de carregamento da biblioteca é o problema.
No Unices (em geral), os segmentos de código das Bibliotecas compartilhadas (DLL's) são realmente compartilhados.
O Windows NT carrega uma cópia da DLL por processo, porque ele manipula o segmento de código da biblioteca (e o segmento de código executável) após o carregamento. (Diz onde estão seus dados?)
Isso resulta em segmentos de código em bibliotecas que não são reutilizáveis.
Portanto, o processo de criação do NT é realmente muito caro. E no lado negativo, faz com que o DLL não economize de forma apreciável na memória, mas uma chance para problemas de dependência entre aplicativos.
Às vezes, vale a pena para a engenharia dar um passo atrás e dizer: "agora, se fôssemos projetar isso para realmente uma merda, como seria?"
Trabalhei com um sistema embarcado que era bastante temperamental uma vez, e um dia olhei para ele e percebi que era um magnetron de cavidade, com a parte eletrônica na cavidade de microondas. Depois disso, o tornamos muito mais estável (e menos parecido com um micro-ondas).
fonte
A resposta curta é "camadas e componentes de software".
A arquitetura do Windows SW tem algumas camadas e componentes adicionais que não existem no Unix ou são simplificados e manipulados dentro do kernel no Unix.
No Unix, fork e exec são chamadas diretas ao kernel.
No Windows, a API do kernel não é usada diretamente, há win32 e alguns outros componentes em cima dela, portanto, a criação do processo deve passar por camadas extras e, em seguida, o novo processo deve ser iniciado ou se conectar a essas camadas e componentes.
Por algum tempo, pesquisadores e corporações tentaram quebrar o Unix de uma forma vagamente semelhante, geralmente baseando seus experimentos no kernel Mach ; um exemplo conhecido é o OS X .. Cada vez que eles tentam, no entanto, fica tão lento que eles acabam, pelo menos parcialmente, mesclando as peças de volta ao kernel permanentemente ou para remessas de produção.
fonte
Como parece haver alguma justificativa para o MS-Windows em algumas das respostas, por exemplo
Agora, vejamos os fatos, qual é a diferença de desempenho?
Dados resumidos de http://www.bitsnbites.eu/benchmarking-os-primitives/ .
Como o preconceito é inevitável, ao resumir, fiz isso em favor do Hardware MS-Windows
para a maioria dos testes i7 8 core 3.2GHz. Exceto Raspberry-Pi executando Gnu / Linux
Notas: No Linux,
fork
é mais rápido que o método preferido do MS-WindowCreateThread
.Números para operações de tipo de criação de processo (porque é difícil ver o valor do Linux no gráfico).
Em ordem de velocidade, do mais rápido para o mais lento (os números são o tempo, menor é melhor).
Números para outras medidas
fonte
Além disso, há o fato de que na máquina Win, muito provavelmente, um software antivírus será ativado durante o CreateProcess ... Essa é geralmente a maior lentidão.
fonte
Também é importante notar que o modelo de segurança no Windows é muito mais complicado do que em sistemas operacionais baseados em Unix, o que adiciona muita sobrecarga durante a criação do processo. Mais uma razão pela qual o multithreading é preferido ao multiprocessamento no Windows.
fonte
fork()