No linux, há realmente muita diferença entre um processo de bifurcação e um processo de criação de um novo encadeamento?

Sim, e é uma diferença bastante substancial, principalmente em arquiteturas como MIPS e PPC, onde grande parte do código de gerenciamento de tabela de páginas está em software.

Vou ficar um pouco "acenando as mãos" aqui, porque esta pergunta indica que uma explicação detalhada completa, passo a passo, provavelmente não é uma resposta útil para a pergunta.

Também o torna mais aplicável ao UNIX e outros UNIX como sistemas operacionais.

Nota: Também vou ignorar especificamente sfork (), vfork () e posix_spawn () e suas variantes, e falarei apenas sobre fork (), em particular.

Quando um processo bifurca, ele aloca uma nova estrutura de processo (naturalmente), pega uma referência de credencial adicional na credencial de processos anterior e cria uma nova tabela de arquivos abertos por processo.

Em seguida, duplica todos os descritores de arquivo do processo antigo para o novo, exceto os marcados como "fechar no garfo".

Ele também aloca uma nova pilha e copia todo o conteúdo antigo da pilha.

E então começa o trabalho caro.

Ele cria um novo espaço de endereço virtual para o novo processo e, em seguida, para o novo processo, pega referências em todas as páginas antigas do processo e as marca como "COW" - cópia na gravação - para que, se um processo modifique uma dessas páginas compartilhadas , uma nova página de suporte de hardware é alocada, o conteúdo anterior é copiado para a nova página e a falha de gravação na página antiga é atendida e essa página é marcada como "gravável".

Copiar o espaço de endereço é a coisa mais cara que você pode fazer quando bifurca.

E então vai.

Quando você cria um encadeamento, praticamente aloca uma nova estrutura de estado do encadeamento (uma é alocada por padrão para cada processo “principal” à medida que a estrutura proc é alocada) e aloca uma nova pilha e, em seguida ... você segue.

Quase tudo que segue um pthread_create () - exceto esse pequeno bloco de estado chamado “armazenamento local do thread” - é compartilhado com o thread principal original (ou o thread que criou o novo thread) no processo.

Grande diferença, certo?