Processos

 

 

Estados principais de um Processo:

São possíveis quatro transições:

 

 

Contexto de um Processo

 

É toda a informação necessária à descrição completa do estado actual de um processo:

 

 

Nível de um Processo

 

Resulta do facto de um processo depender de outro, ser colocado a um nível inferior:

 

 

Gestão de Processos

 

Processos que executam funções como :

 

 

Protecção de Processos

 

De modo a evitar que um processo do utilizador tenha acesso a um processo do supervisor, ou mesmo de outros utilizadores, é necessário garantir a integridade do sistema. Esta integridade deve basear-se em duas partes:

 

 

Sincronização de Processos

A sincronização de processos é necessária para controlar a ordem em que cada processa opera sobre os dados e recursos partilhados.

 

 

Comutação de Processos

 

Os processos do utilizador cooperam com processos de mais alto nível de prioridade, actuando concorrentemente sobre o mesmo CPU. É necessário escolher o melhor algoritmo de escalonamento para a atribuição de tempo de CPU a cada processo.

A comutação deve ter em conta vários aspectos:

Uma das técnicas mais usadas é a preempção ( técnica de suspender processos durante um período de tempo).

 

 

System Calls para manuseamento de Processos

 

fork() - única maneira de criar um processo em Unix.

 

n = wait (estado) - obriga o pai a esperar pela terminação de qualquer processo. A n é associado o pid do primeiro processo filho que terminar e o respectivo valor de retorno é associado a estado.

 

exit(estado) - termina um processo filho, retornando estado como valor de saída. O estado é guardado na tabela de processos, na qual o respectivo processo à assinalado com Zombie, até o pai o ir buscar através da system call wait (ou quando terminar a sua execução) , originando assim uma eliminação definitiva da tabela de processos.

 

n=getpid() - associa a n o valor do pid do processo corrente.

 

n= getppid() - associa a n o valor do pid do pai do processo corrente.

 

sleep(n) - adormece o processo corrente durante n segundos.

 

a = WEXITSTATUS(n) - a variável a fica com o valor dos 8 bits menos significativos de n.

 

 

Funcionamento de Algumas System Calls

 

fork ( int pid = fork() )

  1. Verifica se há lugar na Tabela de Processos;
  2. Tenta alocar memória para o filho;
  3. Altera mapa de memória e copia para a tabela;
  4. Copia imagem do pai para o filho;
  5. Copia para a tabela de processos a informação do processo pai (pid, prioridades, estado, etc);
  6. Atribui um pid ao filho
  7. Informa o Kernel (Núcleo do Sistema Operativo) e o sistema de ficheiros que foi criado um novo processo.

 

exit (exit(int estado) )

O funcionamento depende do pai estar à espera ou não.

 

wait (int pid=wait(int *estado) )

Obriga o processo a esperar pelo fim de um filho de modo a libertar o espaço correspondente na tabela e originar uma eliminação definitiva.

 

Nota: Se um processo estiver em wait e receber um sinal, este desbloqueia de imediato.

 

 

 Exemplo

 

#include <unistd.h>

#include <sys/wait.h>

#include <sys/types.h>

 

main()

{

pid_t pid, pid2;

int estado;

pid = fork(); /* Cria um PROCESSO */

if (pid < 0)

{

printf("Erro ao criar o processo\n");

exit(-1);

}

else

if (pid >0) /* Código que só vai ser executado pelo Processo PAI */

{

printf("Eu sou o PAI\n");

pid2 = wait(&estado);

printf("O filho com o pid %d terminou\n",pid2);

}

else /* Código que só vai ser executado pelo Processo FILHO */

printf("Processo Filho\n");

printf("REPETIDO\n");

}

 

 

Exercícios:

 

1- Considere a seguinte parte  de um programa:

 

...

 

p = fork();

a = fork();

 

printf("Sistemas Operativos II\n");

 

...

 

a)      Quantas vezes é apresentada "Sistemas Operativos II" ? Justifique.

b)      Quantos processos são criados pelo programa?

 

 

2- Faça um programa que crie 2 processos e:

 

  

3- Considere o seguinte pedaço de código em C:

 

 

for (i=0; i<4; i++ )

   pid = fork();

 

printf(“SOP2\n”);

 

            a) Quantos processos são criados por este programa? Justifique.

            b) Quantas vezes é apresentado “SOP2”? Justifique.

 

 

4- Considere a seguinte parte de um programa:

 

main()

{

...

pid2=0;

for(i=0;i<2;i++)

{

            pid=fork();

            if (pid==0)

                        pid2=fork();

            if (pid2==0)

                        printf(“Exame de SO2\n”);

           

}

 

...

}

 

Quantas vezes é apresentada a frase “Exame de  SO2” ? Justifique.

 

 

5– Considere a seguinte parte de um programa:

 

main ()

{

       ...

 

       for(i=0; i<2: i++)

       {

             pid1=fork();

             pid2=fork();

             if (pid1 > 0)

                    printf("Sistemas\n");

             if (pid2 == 0)

                    printf("Operativos\n");

       }

       ...

}

 

Quantas vezes são apresentadas as palavras "Sistemas" e "Operativos"? Justifique.

 

Nota: Considere que a função fork() nunca devolve valores menores que zero.

 

 

6- Tendo um array de inteiros com mil posições, crie um processo e faça o seguinte:

 

 

7- Implemente um programa que obtenha a “funcionalidade” apresentada no seguinte diagrama:

 

 

 

Nota: A função void M(char *) apresenta no monitor uma string;

 

 

8- Faça um programa que crie 6 processos e:

1º processo: 1 .. 200

2º processo: 201 .. 400

3º processo: 401 .. 600

4º processo: 601 .. 800

5º processo: 801 .. 1000

6º processo: 1001 .. 1200

 

 

9- Tendo um array de 1000 posições, faça um programa que crie 5 processos e:

 

Nota: O array não tem números repetidos.

 

 

10- Crie a seguinte função:

 

a)      char cria_gémeos(pid_t lista[2]) – esta função deve criar dois processos e devolver para o primeiro processo criado  o caracter ‘a’ e para o segundo processo o caracter ‘b’. Para o pai, a função devolve o caracter ‘p’ assim como os identificadores dos processos criados.

 

b)      Utilize a função da alínea anterior em substituição da função fork para resolver o exercício 8.