%20de%20processos%20em%20Linux.png)
Pelo que entendi, os descritores de processos são armazenados em uma estrutura de dados de lista duplamente vinculada. Mas fork
pode ser usado para criar vários filhos para o mesmo processo, o que me faz pensar que existe uma estrutura em árvore, porque vários processos apontarão para um processo pai. Qual é correto? Os descritores de processos são diferentes dos processos?
Responder1
fork()
cria um novo processo copiando o descritor do processo. Conseqüentemente, os dois processos compartilham (pelo menos inicialmente) alguns dados, mas assim que um processo é iniciadomudandonele, o mecanismo de cópia na gravação garante que a alteração seja localizada apenas no processo que realmente a fez. É o mecanismo padrão para geração de processos no UNIX.
É claro que isso cria uma relação pai-filho bastante natural entre os processos, mas isso é independente da representação interna no kernel. Os descritores de processos podem ser implementados como uma lista vinculada, árvore, tabela hash ou qualquer outra estrutura (mais ou menos) adequada. Tudo o que realmente é necessário é colocar no descritor de processo do kernel que aponta para o processo pai (e possivelmente também para os processos filhos). Se é ou não usado como parte fundamental da estrutura é uma decisão de design. Uma das muitas coisas que entram em jogo ao decidir tal coisa é, por exemplo, o que acontece quando o processo pai termina - no UNIX, o init
processo adota processos órfãos (com todos os seus processos filhos).
Responder2
Sua confusão decorre da mistura de duas coisas: (1) manter os descritores do processo organizados e (2) o relacionamento pai/filho.
Você não precisa do relacionamento pai/filho para decidir qual processo será executado em seguida ou (em geral) para qual processo enviar um sinal. Então, o Linux task_struct
(que encontrei linux/sched.h
para a fonte do kernel 3.11.5) tem:
struct task_struct __rcu *real_parent; /* real parent process */
struct task_struct __rcu *parent; /* recipient of SIGCHLD, wait4() reports */
/*
* children/sibling forms the list of my natural children
*/
struct list_head children; /* list of my children */
struct list_head sibling; /* linkage in my parent's children list */
Você está correto, existe uma estrutura de árvore para o relacionamento filho/pai, mas parece estar oculta em outra lista e em um ponteiro para o pai.
A famosa lista duplamente vinculada não é óbvia na struct task_struct
definição da estrutura 3.11.5. Se eu li o código corretamente, o elemento struct não comentado struct list_head tasks;
é a lista duplamente vinculada "organizadora", mas posso estar errado.