Os threads são copiados ao chamar o fork?


31

Se eu tiver um programa em execução com threads e chamar fork()um sistema baseado em unix, as threads serão copiadas? Eu sei que a memória virtual para o processo atual é copiada 1: 1 para o novo processo gerado. Eu sei que os threads têm sua própria pilha na memória virtual de um processo. Assim, pelo menos a pilha de threads também deve ser copiada. No entanto, não sei se há algo mais nos threads que não reside na memória virtual e, portanto, NÃO é copiado. Se não houver, os dois processos compartilham os encadeamentos ou são cópias independentes?

Respostas:


29

Não.

Threads não são copiados fork(). A especificação POSIX diz (enfatizar é meu):

fork - crie um novo processo

Um processo deve ser criado com um único encadeamento . Se um processo multiencadeado chamar fork (), o novo processo deverá conter uma réplica do encadeamento de chamada e todo o seu espaço de endereço, possivelmente incluindo os estados de mutexes e outros recursos. Conseqüentemente, para evitar erros, o processo filho só pode executar operações seguras de sinal assíncrono até que uma das funções exec seja chamada.

Para contornar esse problema, existe uma pthread_atfork()função para ajudar.


7

garfo de homem :

O processo filho é criado com um único thread - aquele que chamou fork (). Todo o espaço de endereço virtual do pai é replicado no filho, incluindo os estados de mutexes, variáveis ​​de condição e outros objetos pthreads; o uso de pthread_atfork (3) pode ser útil para lidar com problemas que isso pode causar.


Mas isso parece estranho: por que a pilha dos threads no processo que chama o fork é copiada se os threads reais (que eu não conheço contêm armazenamento em outro lugar que não a memória virtual) não são?

Bem, o porquê disso é uma questão completamente diferente. Não conheço as decisões de design originais que levaram a essa implementação. Se você estiver interessado, faça isso como uma pergunta separada.
kaylum 14/04

@ dip mas pilha de outros threads não são copiados, quem disse isso?
Jean-Baptiste Yunès

11
@ Jean-BaptisteYunès Nos sistemas unix, existe uma estrutura que representa a memória virtual de um processo. Esse é o único copiado. Não é só o heap e bss

6
você obtém todo o espaço da memória - e, portanto, as pilhas de todos os threads. você precisa disso porque não há limitação para onde os ponteiros que vivem na pilha (ou memória estática) acessível para o segmento restante estão apontando - eles podem muito bem estar apontando para dados que viveram na pilha de algum segmento no processo original
davidbak

4

From The Open Group Base de Especificações Edição 7, 2018 Edition garfo :

Um processo deve ser criado com um único encadeamento. Se um processo multiencadeado chamar fork () , o novo processo deverá conter uma réplica do encadeamento de chamada e todo o seu espaço de endereço, possivelmente incluindo os estados de mutexes e outros recursos. Conseqüentemente, para evitar erros, o processo filho só pode executar operações seguras de sinal assíncrono até que uma das funções exec seja chamada.

Quando o aplicativo chama fork () de um manipulador de sinal e qualquer um dos manipuladores de fork registrados por pthread_atfork () chama uma função que não é segura para sinal assíncrono, o comportamento é indefinido.


-2

Originalmente, o "fork" era obtido gravando a tarefa no disco e, em vez de ler em um thread diferente (o que seria feito se a tarefa fosse trocada por outra diferente), modificando o ID da tarefa da imagem ainda na memória e continuando com sua execução (como a nova tarefa). Essa foi uma modificação muito simples do mecanismo básico de troca de tarefas, em que apenas uma tarefa ocuparia memória RAM de cada vez.

Obviamente, à medida que o gerenciamento de memória ficou mais elaborado, esse esquema foi modificado para se adequar ao novo ambiente.


Curioso por que isso foi rejeitado. Foi assim que o Unix fez.
Hot Licks

Esse é um insight interessante, mas onde ele menciona tópicos? Não parece uma resposta para mim.
wastl 15/04
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.