Sistemas de Operação

Aula Prática 3: Comunicação entre Processos

Esta aula tem por objectivo familiarizá-lo com as operações básicas de manipulação de pipes (canos) e de sinais em ambientes UNIX. Para tal, deverá implementar pequenos programas que respondam aos requisitos de cada uma das tarefas que se seguem. Para obter mais informação sobre as funções de sistema referidas, consulte as man-pages correspondentes.

  1. Enviar mensagens através de uma pipe: o programa deve criar um processo filho e enviar-lhe duas mensagens, "Hello world!" e "Goodbye!", terminando em seguida. Por sua vez, o processo filho deverá imprimir para o ecrã as mensagens à medida que as for recebendo, terminando assim que o processo pai feche a ligação. Não se esqueça de, em cada um dos processos, fechar os descritores que não vão ser usados. Funções a ter em conta: pipe, write, read e close.
  2. Saída paginada: o programa deve criar um processo filho para paginar no ecrã as mensagens do processo pai. O processo pai deve enviar ao processo filho a seguinte sequência de linhas:
      Linha 1
      Linha 2
      ...
      Linha 100
    O processo filho deve executar o programa more para paginar no ecrã a sequência de linhas recebida do processo pai. Como o paginador more precisa de ter acesso exclusivo ao terminal, o processo pai não deve terminar antes do processo filho. Funções a ter em conta: dup2, wait e família de funções exec.
  3. Apanhar sinais: o programa deve definir um handler para apanhar os sinais SIGTSTP (enviado pelo terminal quando se usa CTRL-Z) e SIGINT (enviado pelo terminal quando se usa CTRL-C), imprimindo nesses casos uma mensagem adequada. O programa deve começar por imprimir o seu PID, instalar de seguida o handler, e finalmente entrar num ciclo infinito até receber o sinal SIGKILL. Para enviar o sinal SIGKILL ao processo deverá invocar numa outra shell o comando kill -9 para o PID que o programa imprimiu. Funções a ter em conta: signal e pause.
  4. Sincronização por sinais: o programa deve criar um processo filho e ambos os processos (pai e filho) devem imprimir alternadamente linhas, de modo a obter uma sequência semelhante à seguinte:
      Pai: 1 
      Filho: 2 
      Pai: 3 
      Filho: 4 
      ...  
      Pai: 19
      Filho: 20
    O processo pai deve imprimir as linhas ímpares e o processo filho as linhas pares, até atingirem um determinado valor (20 no exemplo). Para indicar ao outro a sua vez de imprimir, os processos devem trocar sinais do tipo SIGUSR1. Funções a ter em conta: kill.