LFA – Gerenciamento de Processos no Linux
O segundo post da série LFA – Linux de uma Forma Acadêmica, nós vamos abordar como funciona o gerenciamento de processos no kernel do Linux.
O que é um processo?
Em qualquer sistema operacional, o processo é a representação de um programa em execução, e faz uso dos recursos do computador, como as memórias, e o processador, para realizar a tarefa para qual foi desenvolvido, segundo Tannebaum (2005, pag 26)“[...] Um processo é uma abstração utilizada para representar um programa em execução. Um processo contém toda informação necessária para completar uma computação.[...]”, é de responsabilidade do sistema operacional organizar e gerenciar todos esses processos.
Processos e tarefas no Linux.
No Linux os processos e threads são chamados de tarefas e representados como a mesma estrutura de dados, o gerenciador de processos mantém uma lista de todas as tarefas usando como base duas estruturas de dados. A primeira é uma lista circular, com dois encadeamentos, onde cada entrada contém ponteiros para as tarefas anteriores e posteriores. Essa estrutura é acessada quando o kernel precisa examinar todas as tarefas do sistema. A segunda é uma tabela hash, uma estrutura de dados que associa chaves de pesquisa a valores. Seu objetivo é, a partir de uma chave simples, fazer uma busca rápida e obter o valor desejado.
Um sistema operacional como o Linux possui uma infinidade de processos sendo gerenciados, e para facilitar a sua classificação e gerenciamento, possuem algumas características: A primeira delas é o PID (Process Identifier), assim que uma tarefa é criada ela recebe um número de identificação único. Os identificadores de processos ou PID são passados para uma função hash e assim determinar a sua localização na tabela de processos, com isso o kernel possui um acesso rápido a uma tarefa específica apenas conhecendo o seu PID.
O processo possui uma estrutura chamada task_struct, que reside em ./linux/include/linux/sched.h. e também chamada de PCB (Process Control Block) ou bloco de controle de processos que armazena variáveis e estruturas contendo informações que o descrevem. Essa estrutura contém todos os dados necessários para representar o processo, junto com um conjunto de outros dados para contabilidade, e para manter relacionamentos com outros processos (pais e filhos).
Segundo Deitel (2005, )
[...] O núcleo mantém o PCB de um processo em uma região protegida da memória que os processos de usuário não podem acessar. Em sistemas UNIX, um PCB armazena informações, incluindo os conteúdos dos registradores e dos processos , o identificador de processo PID […]‘.
No Linux existe vários estados diferentes de execução, armazenados na estrutura task_struct.
Segundo Avinesh Kumar (2009, Estados do Processo), >kernel possui os seguintes estados:
TASK_RUNNING: O processo está em execução na CPU ou aguardando em uma fila de execução para ser planejado.
TASK_INTERRUPTIBLE: O processo está inativo, aguardando algum evento ocorrer. O processo está aberto para ser interrompido por sinais. Uma vez sinalizado ou ativado pela chamada de ativação explícita, o processo faz transição paraTASK_RUNNING.
TASK_UNINTERRUPTIBLE: O estado do processo é semelhante aTASK_INTERRUPTIBLEexceto que nesse estado ele não processa sinais. Pode até não ser desejável interromper o processo enquanto nesse estado, pois ele pode estar no meio da conclusão de alguma tarefa importante. Quando o evento que ele está aguardando ocorre, o processo é ativado pela chamada de ativação explícita.
TASK_STOPPED: A execução do processo está parada, ele não está em execução e não está apto para ser executado. No recebimento de sinais comoSIGSTOP,SIGTSTP, e assim por diante, o processo chega nesse estado. O processo seria executável novamente após o recebimento do sinalSIGCONT.
TASK_TRACED: Um processo chega nesse estado enquanto está sendo monitorado por outros processos, como depuradores.
EXIT_ZOMBIE: O processo foi finalizado. Ele está demorando simplesmente para seu pai coletar algumas informações estatísticas sobre ele.
EXIT_DEAD: O estado final (exatamente como parece). O processo atinge esse estado quando estiver sendo removido do sistema, pois seu pai acaba de coletar todas as informações estatísticas emitindo a chamada do sistemawait4()ouwaitpid().
Cada processo em questão precisa possuir um proprietário, ou seja, quem o criou e possui os privilégios para gerencia-lo, com isso o sistema sabe, através das permissões fornecidas pelo proprietário, quem executou o processo em questão. Para lidar com os donos, o sistema usa os números UID a identificação de usuário e GID Grup Indetifier) a identificação de grupo. No UNIX organiza os usuários dentro de grupos específicos, dando assim permissões para determinados grupos de usuários, para facilitar a organização e aumentar a segurança.
No próximo post falaremos dos Escalonadores de Processos do Linux.