O Linux usa um modelo de segmentação 1-1, sem (para o kernel) nenhuma distinção entre processos e threads - tudo é simplesmente uma tarefa executável. *
No Linux, a chamada do sistema clone
clona uma tarefa, com um nível configurável de compartilhamento, entre os quais:
CLONE_FILES
: compartilhe a mesma tabela de descritor de arquivo (em vez de criar uma cópia)
CLONE_PARENT
: não estabeleça uma relação pai-filho entre a nova tarefa e a antiga (caso contrário, getppid()
= pai getpid()
)
CLONE_VM
: compartilhe o mesmo espaço de memória (em vez de criar um COW cópia )
fork()
chamadas clone(
menos compartilhamento )
e pthread_create()
chamadasclone(
mais compartilhamento )
. **
fork
Isso custa um pouco mais do que o custo pthread_create
por causa da cópia de tabelas e da criação de mapeamentos de COW para memória, mas os desenvolvedores do kernel do Linux tentaram (e conseguiram) minimizar esses custos.
A alternância de tarefas, se compartilharem o mesmo espaço de memória e várias tabelas, será um pouco mais barata do que se não forem compartilhadas, porque os dados já podem estar carregados no cache. No entanto, a alternância de tarefas ainda é muito rápida, mesmo que nada seja compartilhado - isso é algo que os desenvolvedores de kernel do Linux tentam garantir (e conseguem garantir).
De fato, se você estiver em um sistema com vários processadores, o compartilhamento não será realmente benéfico para o desempenho: se cada tarefa estiver sendo executada em um processador diferente, a sincronização da memória compartilhada será cara.
* Simplificado. CLONE_THREAD
faz com que a entrega de sinais seja compartilhada (que precisa CLONE_SIGHAND
, que compartilha a tabela do manipulador de sinais).
** simplificado. Existem dois SYS_fork
e SYS_clone
syscalls, mas no kernel, o sys_fork
e sys_clone
são invólucros muito finos com a mesma do_fork
função, que por si só é um invólucro fino copy_process
. Sim, os termos process
, thread
e task
são usados em vez de forma intercambiável no kernel do Linux ...