quarta-feira, setembro 08, 2010

Aula 4 de Sistemas Operacionais Abertos



Processos




Introdução

  • Os processos contém, além do código de execução (text section), os recursos usados (como arquivos abertos), sinais, dados internos do kernel, um espaço de endereços na memória, e uma seção de dados (data section), contendo variáveis globais.


  • Um processo pode conter várias threads de execução (threads). no Linux, um thread é um processo especial, de modo que o tratamento de threads é o mesmo de processos.


  • Um processo inicia no Linux através da chamada de sistema fork(), que cria um processo duplicando outro. O kernel retorna duas vezes de fork(): uma vez para o processo que chamou fork (o processo pai) e outra vez para o processo que foi criado (o processo filho).




  • Em geral, o processo filho chama uma das funções da família exec() para criar um novo espaço de memória e susbtituir a existente, de modo que o filho realmente distingue-se do pai.




  • Em versões recentes do kernel, a chamada a fork() é implementada por uma chamada a clone(), que atrasa o processo de duplicação do processo pai inteiro, visto que este poderá (ou não) ser substituído pelo filho. Veremos esta implementação do kernel com mais detalhes.

Processos no Kernel

  • O kernel mantém a lista de processos numa lista circular duplamente encadeada chamada task list
  • Cada elemento da lista é chamdo descritor de processo, e é do tipo struct task_struct.
  • Esta estrutura está definida num arquivo de cabeçalho, em <linux/sched.h>
  • Definição de task_struct
Lista de Processos e cada descritor de processos, contendo a struct task_struct

Guardando o descritor de processo

  • Cada processo tem associado a si um ID, chamado PID, que é um tipo pid_t, que é muitas vezes um sinônimo para int, ou, por questões de compatibilidade short int (16 bits). Pode-se modificar o valor em tempo de execução em /proc/sys/kernel/pid_max.
  • No kernel,. os processos são referenciados pelo endereço de memória (ponteiro) de sua task_struct. Cada processo tem uma, e ela está em alguma posição de memória. Existe uma macro que guarda este ponteiro, chamada current, que contém o endereço do processo EM EXECUÇÃO.
    • No PowerPC, este endereço está num registrador.
    • No x86, este endereço está na região de memória do processo, em geral na mesma posição relativa, possibilitando que um código em linguagem de montagem recupere este valor rapidamente.
Estados dos Processos

A task_struct contém um campo state, que pode ter os seguintes valores:

  • volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */
As possibilidades  para os processos (tasks) rodando são:
  • TASK_RUNNING: O processo pode rodar, ou está rodando, ou está numa runqueue (fila de execução.
  • TASK_INTERRUPTIBLE: O processo está "dormindo", esperando para ser posto em execução novamente.
  • TASK_UNINTERRUPTIBLE: O mesmo, mas o processo NÃO responde ao envio de sinais (que é um dos mecanismos de comunicação entre-processos visto em Sistemas Operacionais).

Manipulando o estado atual do processo



  • set_task_state(task, state). Ajusta a tarefa (processo) task para estar no estado state.


Nenhum comentário: