Qual é a diferença entre fork e thread?


Respostas:


94

Uma bifurcação fornece um processo totalmente novo, que é uma cópia do processo atual, com os mesmos segmentos de código. Conforme a imagem da memória muda (normalmente isso ocorre devido ao comportamento diferente dos dois processos), você obtém uma separação das imagens da memória (cópia na gravação), porém o código executável permanece o mesmo. As tarefas não compartilham memória, a menos que usem alguma primitiva de comunicação entre processos (IPC) .

Um processo pode ter vários threads, cada um executando em paralelo no mesmo contexto do processo. Memória e outros recursos são compartilhados entre threads, portanto, os dados compartilhados devem ser acessados ​​por meio de alguns objetos primitivos e de sincronização (como mutexes , variáveis ​​de condição e semáforos ) que permitem evitar a corrupção de dados.


3
Você provavelmente quer se referir a "cópia do processo atual" como um processo filho.

1
O segmento de texto, entretanto, é freqüentemente compartilhado (virtualmente) e até mesmo o segmento de dados pode ser copiado na gravação.
Jé Queue


76

Garfo

Fork nada mais é que um novo processo que se parece exatamente com o antigo ou o processo pai, mas ainda é um processo diferente com ID de processo diferente e tendo sua própria memória. O processo pai cria um espaço de endereço separado para o filho. Ambos os processos pai e filho possuem o mesmo segmento de código, mas são executados independentemente um do outro.

O exemplo mais simples de bifurcação é quando você executa um comando no shell no Unix / Linux. Cada vez que um usuário emite um comando, o shell bifurca um processo filho e a tarefa é concluída.

Quando uma chamada de sistema fork é emitida, uma cópia de todas as páginas correspondentes ao processo pai é criada, carregada em um local de memória separado pelo SO para o processo filho, mas em certos casos, isso não é necessário. Como nas chamadas de sistema 'exec', não há necessidade de copiar as páginas do processo pai, pois execv substitui o espaço de endereço do próprio processo pai.

Algumas coisas a serem observadas sobre bifurcação são:

  • O processo filho terá seu próprio ID de processo exclusivo.
  • O processo filho deve ter sua própria cópia do descritor de arquivo do pai.
  • Os bloqueios de arquivo definidos pelo processo pai não devem ser herdados pelo processo filho.
  • Quaisquer semáforos que estão abertos no processo pai também devem ser abertos no processo filho.
  • O processo filho deve ter sua própria cópia dos descritores da fila de mensagens do pai.
  • A criança terá seu próprio espaço de endereçamento e memória.

Tópicos

Threads são processos de peso leve (LWPs). Tradicionalmente, um thread é apenas um estado de CPU (e algum outro estado mínimo) com o processo contendo o resto (dados, pilha, E / S, sinais). Threads requerem menos sobrecarga do que “bifurcar” ou gerar um novo processo porque o sistema não inicializa um novo espaço de memória virtual de sistema e ambiente para o processo. Embora seja mais eficaz em um sistema multiprocessador, onde o fluxo do processo pode ser programado para ser executado em outro processador, ganhando velocidade por meio do processamento paralelo ou distribuído, os ganhos também são encontrados em sistemas uniprocessadores que exploram a latência em I / O e outras funções do sistema que podem interromper o processo execução.

Threads no mesmo processo compartilham:

  • instruções de processo
  • a maioria dos dados
  • arquivos abertos (descritores)
  • sinais e manipuladores de sinais
  • diretório de trabalho atual
  • usuário e id de grupo

Mais detalhes podem ser encontrados aqui .


2
Um processo pode ter vários threads. Se um dos threads em um processo chamar fork, o processo bifurcado tem uma memória totalmente duplicada, mas apenas o thread de chamada está no novo processo?
Michael


29

A resposta do Dacav é excelente, eu só queria acrescentar que nem todos os modelos de threading oferecem um verdadeiro multiprocessamento.

Por exemplo, a implementação de threading padrão do Ruby não usa threads verdadeiros do SO / kernel. Em vez disso, ele imita ter vários threads alternando entre os objetos Thread dentro de um único thread / processo do kernel.

Isso é importante em sistemas multiprocessador / multi-core, porque esses tipos de threads leves só podem ser executados em um único núcleo - você não obtém muito aumento de desempenho por ter vários threads.

O outro lugar em que isso faz a diferença é quando um thread bloqueia (esperando por I / O ou chamando o IOCTL de um driver), todos os Threads bloqueiam.

Isso não é muito comum hoje em dia - a maioria das implementações de threading usa threads de kernel que não sofrem com esses problemas - mas vale a pena mencionar para integridade.

Em contraste, fork fornece outro processo que pode ser executado simultaneamente em outra CPU física enquanto o processo original está sendo executado. Algumas pessoas consideram o IPC mais adequado para seu aplicativo, outras preferem o threading.

Boa sorte e divirta-se! Multi-threading é desafiador e gratificante.


7
+1 para acertar um nervo: "nem todos os threads oferecem multiprocessamento verdadeiro"
Dacav

5

Threads são funções executadas em paralelo, fork é um novo processo com herança de pais. Threads são bons para executar uma tarefa em paralelo, enquanto garfos são processos independentes, que também funcionam simultaneamente. Threads têm condições de corrida e semáforos de controles e bloqueios ou mutexes, tubos podem ser usados ​​em fork e thread.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.