Skip to content

Laboratório de Sistemas Operativos sobre comunicação entre processos usando sinais (signals)

Notifications You must be signed in to change notification settings

tecnico-so/lab_signals

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Guião sobre signals

IST

Objetivos

No final deste guião, deverá ser capaz de:

  • Explicar o que é um signal e como se usa para controlar processos do sistema operativo;
  • Programar o tratamento de sinais assíncronos.

Introdução

Um sinal (signal) é uma mensagem assíncrona que pode ser enviada a qualquer momento para um processo ativo. O sistema operativo interrompe o fluxo normal de execução do processo para este tratar o sinal. O objetivo do envio do signal é provocar um comportamento específico, como a sua terminação, por exemplo. O tratamento de um sinal está predefinido, mas pode ser criada uma rotina para tratar este sinal como vamos ver a seguir.

Qualquer chamada a uma função durante a rotina de tratamento do sinal deverá ser segura (Async-Signal-Safe ou abreviadamente AS-Safe).
Por exemplo, a função printf mantém dados alocados, como ponteiros e indíces para efetuar buffered I/O. Se, durante a execução do programa, uma chamada à função printf for interrompida por um sinal, uma nova chamada à função printf durante a rotina de tratamento do signal resultará em comportamento indefinido, ou seja, poderá criar situações de erro inesperadas.

1. Comando kill

O envio de sinais pode ser feito com o comando kill que, por omissão, envia um sinal para pedir ao processo para terminar (daí o nome do comando). O nome do comando poderia ser algo como send signal, dado que permite enviar qualquer sinal, mas o nome original permanece. O envio de sinais é apenas permitido ao utilizador dono do processo ou ao super-utilizador.

O envio de sinais pode ser feito com o comando kill das seguintes formas:

$ kill -s TERM 1234
$ kill -TERM 1234

TERM corresponde ao sinal que pretendemos enviar.
Pode consultar a lista de possíveis sinais com o comando: kill -L. A lista vai variar entre diferentes versões de Unix.

1234 corresponde ao identificador do processo (Process ID ou apenas PID) a que pretendemos enviar o sinal.
Pode consultar a lista de processos ativos com o comando: ps (ou top ou pgrep).

Pergunta: Qual é o sinal enviado por omissão com o comando kill 1234?
(Sugestão: procure a resposta a página no manual, com o comando: man kill)

Caso um programa não responda ao sinal de terminação ordeira (SIGTERM), pode ser usado o sinal para terminação forçada (SIGKILL), normalmente associado ao comando kill -9.

2. Exemplo intquit.c

  1. Clone este repositório, usando o git: git clone https://github.com/tecnico-so/lab_signals.git
  2. Estude o programa intquit.c:
    • Repare na definição da função sig_handler(), que será chamada assincronamente para tratar o sinal, quando o processo o receber;
    • Repare nos tratamentos do SIGINT (linha 16) e do SIGQUIT (linha 27);
    • A função signal() regista a rotina de tratamento para estes sinais (linhas 37 e 39). Neste caso, a mesma rotina sig_handler() (nome escolhido pelo programador), vai ser registada para tratar dois sinais diferentes (SIGINT e SIGQUIT), mas poderiam ser configuradas rotinas diferentes;
  3. Compile o programa com a ferramenta make (dentro da pasta src/);
  4. Corra o programa (./intquit);
  5. Observe que o programa inicia e fica num ciclo infinito ou parado.
  6. Experimente fazer CTRL-C (que envia SIGINT) e observe o resultado.
  7. Repita o passo anterior.
  8. Experimente fazer CTRL-\ (que envia SIGQUIT) e observe o resultado.

3. Exercício SIGTERM

  1. Adicione o tratamento do sinal SIGTERM numa nova função chamada term_handler().
  2. Compile e teste.

Notas: Não é possível enviar o sinal SIGTERM com um atalho como outros sinais. Para testar o código deveram:

  1. Parar o processo com o sinal SIGSTOP através do atalho CTRL-Z.
  2. Inspecionar o pid do vosso processo com o comando ps.
  3. Envir o sinal SIGTERM com o comando kill pid.
  4. Regressar ao vosso processo com o comando fg.

Conclusão

Neste guião vimos o que são signals e como são úteis para envio de comandos assíncronos para os processos em execução.
O comando kill permite enviar sinais para processos, sendo o mais frequente o sinal que indica ao programa que deve terminar ordeiramente (SIGTERM).
Vimos também um exemplo de código com registo e chamada de uma rotina de tratamento de sinais assíncronos.

Sugestão

Os signals são também usados para o controlo de execução de vários programas numa única sessão de shell, o que se designa por job control. Desta forma é possível ter vários programas a executar, um em primeiro plano (foreground) e outros em segundo plano (background). Fica a sugestão de explorar estas capacidades com os comandos jobs, bg, fg, e com o operador & no fim dos comandos que permite executá-los em background.


Contactos para sugestões/correções: LEIC-Alameda, LEIC-Tagus, LETI

About

Laboratório de Sistemas Operativos sobre comunicação entre processos usando sinais (signals)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •