Instituto Politécnico de Viseu
Escola Superior de Tecnologia de Viseu
Engenharia de Sistemas e Informática
Sistemas Operativos - 2005/2006
Trabalho Prático v1.0
Introdução
O presente trabalho prático visa uma maior familiarização com a programação de mecanismos de
sincronização e comunicação entre processos no ambiente UNIX/Linux. Poderá ser realizado em
grupo, constituído por um número máximo de 3 alunos. O trabalho está sujeito a apresentação e
defesa, realizada individualmente por cada aluno.
É, obviamente, interdita a cópia parcial ou integral de trabalhos e, a ser detectada, conduzirá à
adequada penalização dos envolvidos. O trabalho deverá apresentar-se na forma de código fonte e
de um relatório claro e conciso, que também será objecto de avaliação.
Chama-se à atenção para o facto de este enunciado poder ainda sofrer pequenas alterações. Os
alunos poderão aperceber-se de eventuais actualizações, vigiando a respectiva versão.
Para os alunos mais desatentos, refira-se que a execução deste trabalho prático, para além de
constituir elemento de avaliação, representa também uma forma efectiva de preparação para as
provas de avaliação.
Contextualização
As especificações apresentadas neste enunciado não correspondem à solução mais simples ou
eficiente, devendo ser encaradas como um pretexto para conjugar, num único trabalho prático, um
conjunto alargado de mecanismos de comunicação estudados, nomeadamente, ficheiros, sinais,
pipes unidireccionais standard, pipes nomeados (FIFO), filas de mensagens, memória partilhada e
semáforos.
De modo a simplificar a avaliação deste trabalho, as indicações devem ser integralmente
respeitadas. É, contudo, admissível que sejam tomadas opções diferentes, desde que, claramente,
não representem uma forma de “contornar” algum dos aspectos em estudo. Estas opções devem
encontrar-se devidamente fundamentadas no respectivo relatório. As opções tomadas no sentido
de resolver circunstâncias que aqui não sejam explicitadas deverão, também, ser devidamente
documentadas.
Descrição do problema
O contexto de utilização desta aplicação poderia, por exemplo, corresponder a uma redacção de
um jornal. Várias agências noticiosas enviam notícias à redacção. As agências noticiosas
classificam previamente as notícias por tópicos, como, por exemplo, política, sociedade, desporto,
educação, etc. Os jornalistas da redacção, especializados em determinados tópicos, devem ser
notificados aquando da recepção de novas notícias nesse tópico.
Esta aplicação é constituída por vários programas que interagem entre si, conforme
esquematizado na Figura 1. Todos os processos são executados num mesmo equipamento Linux e
utilizam os mecanismos IPC estudados nas aulas práticas da disciplina.
O programa Servidor serve de plataforma de difusão das notícias no seio da redacção. Cada
programa leitor de notícias (Leitor) subscreve um ou mais tópicos. Sempre que uma notícia é
publicada num tópico, todos os subscritores recebem a correspondente notificação. Se o programa
leitor pretender ter acesso ao conteúdo da notícia, este comunica directamente com o programa
associado a uma agência noticiosa (Agência). O programa Monitor visualiza um conjunto de
estatísticas e informações adicionais sobre a utilização desta aplicação.
1/5
Figura 1
Implementação
Na interacção entre estes processos são definidos vários mecanismos de comunicação de acordo
com a Figura 2.
Figura 2
Programa Servidor
Processo Pai:
Na fase de inicialização, este processo deve preparar convenientemente a estrutura de dados e
criar todos os recursos necessários à comunicação entre processos. A lista de tópicos a serem
considerados deve constar num ficheiro de texto. Todos os dados de configuração da
aplicação (chaves de recursos IPC, subdirectoria de FIFO, etc) devem ser armazenados num
ficheiro de texto para que possa ser consultado pelos restantes programas.
Em seguida, este processo entra em ciclo ficando bloqueado à espera de mensagens (P1, P2)
na fila de mensagens 1. Após a recepção de uma mensagem, lança um processo filho que
tratará de responder ao processo que efectuou o pedido.
Ao receber o sinal SIGINT, deve terminar, libertando todos os recursos que tiverem sido
alocados.
Processo Filho:
2/5
Este processo analisa a mensagem e responde de acordo com os seguintes tipos de mensagens:
Lista tópicos: Este pedido tem origem em processos Agência (P1) ou Leitor (P2). O
processo envia uma resposta (R1 ou R2) com a lista de tópicos definidos no Servidor.
Subscreve tópico: Este pedido tem origem em processos Leitor (P2) que desejam
subscrever um tópico. Não é necessário uma resposta de confirmação da subscrição.
Cancela tópico: Este pedido tem origem em processos Leitor (P2) que desejam cancelar a
subscrição de um tópico. Não é necessário uma resposta de confirmação do cancelamento
da subscrição.
Lista subscrições activas: Este pedido tem origem em processos Leitor (P2) com a
indicação do PID do processo filho que recebe as notificações de novas mensagens. É
enviada uma resposta (R2) com a lista de tópicos subscritos.
Lista de notícias por tópico: Este pedido tem origem em processos Leitor (P2) com
indicação do tópico pretendido. É enviada uma resposta (R2) com a lista de notícias desse
tópico. A lista inclui o número da notícia e o respectivo título.
Processo servidor de notícia: Este pedido tem origem em processos Leitor (P2) com
indicação do número da notícia pretendida. É enviada uma resposta (R2) com o PID do
processo filho Agência que serve o pedido de conteúdo da notícia.
Publica: Pedido de publicação de uma notícia num determinado tópico com origem em
processos Agência (P1). A mensagem correspondente a este pedido deve incluir o tópico,
o título da notícia e o PID do processo que responderá a uma solicitação do conteúdo da
notícia (PID do processo filho Agência). O processo envia uma resposta (R1) com a
indicação do número da notícia (único no sistema). Envia, em seguida, para todos os
processos Leitor que tenham subscrito o tópico, uma mensagem (N1) com informação do
número da notícia e do respectivo título (difusão).
Programa Agência
Este programa permitirá às agências noticiosas, por um lado, solicitar a publicação de uma notícia
num determinado tópico e, por outro, servir os vários processos Leitor que pretendam aceder ao
conteúdo de uma notícia. As notícias estão previamente armazenadas em ficheiros de texto.
Quando lançada a execução deste programa, deve, através da função fork(), lançar um processo
filho. O processo pai será responsável pela interacção com o utilizador. O processo filho será
responsável pela disponibilização do conteúdo de uma notícia solicitado por um processo Leitor.
Processo pai:
O processo pai disponibiliza uma linha de comandos (prompt) que permitirá ao utilizador
introduzir os seguintes comandos:
lt: Pedido ao Servidor da lista de tópicos.
pb <topico> <ficheiro>: O pedido de publicação de uma notícia, num determinado
tópico, é enviado ao Servidor (P1), obtendo deste um número de notícia que é único no
sistema. A informação a enviar ao Servidor inclui o tópico, o título da notícia (1ª linha do
ficheiro de texto) e o PID do processo filho que disponibiliza o conteúdo da notícia. Tal
pedido é solicitado ao servidor através da fila de mensagens 1. O servidor responde (R1)
com um número da notícia e fará a difusão da mesma pelos processos Leitor subscritores
(N1). Recebida a resposta do servidor, o processo pai, através de um pipe unidireccional,
envia ao filho a informação sobre o nome do ficheiro e o respectivo número da notícia e
sinaliza tal facto com o envio de um sinal. O processo filho manterá esta informação numa
tabela, permitindo-lhe responder a solicitações de conteúdos de notícias.
s: Este comando termina o processo, devendo enviar um sinal ao processo filho para que
termine a sua execução.
Processo filho:
Atende a pedidos (F1) de conteúdo de notícias colocadas na fila de mensagens 2. Quando
recebe uma mensagem, esta contém o número da notícia e o remetente (PID do processo
Leitor). Depois de identificado o ficheiro de texto com o conteúdo da notícia, cria um pipe
nomeado (FIFO) para a transferência do conteúdo. Envia uma mensagem de resposta (F2)
para o processo Leitor a confirmar a disponibilidade da notícia. Coloca no FIFO, o conteúdo
do ficheiro de texto correspondente à notícia. A identificação do pipe nomeado coincide com
3/5
o PID do processo Leitor e é criado numa subdirectoria definida pelo programa Servidor (do
conhecimento de ambos os processos comunicantes por consulta do ficheiro de configuração).
Deve ser considerado um número máximo, configurado pelo servidor, de pipes nomeados em
utilização simultânea. O controlo deste número máximo deve ser assegurado por semáforos.
Programa Leitor
Este programa permitirá aos jornalistas, por um lado, utilizar os serviços da aplicação (listar,
subscrever e cancelar tópicos) e, por outro, solicitar à agência noticiosa o conteúdo de uma
determinada notícia.
Processo pai:
O processo pai disponibiliza uma linha de comandos (prompt) que permitirá ao utilizador
introduzir os seguintes comandos:
lt: Pedido ao Servidor da lista de tópicos.
nt <tópico>: Pedido ao Servidor da lista de notícias publicadas neste tópico.
sb <tópico>: Pedido ao Servidor da subscrição de um tópico. Para além do tópico, a
mensagem enviada deve incluir o PID do processo filho que irá receber as notificações de
novas notícias (subscrição). Não é necessário uma resposta de confirmação da subscrição.
csb <tópico>: Pedido ao Servidor do cancelamento da subscrição de um tópico. Não é
necessário uma resposta de confirmação do cancelamento da subscrição.
lts: Pedido ao Servidor da lista de tópicos subscritos. Para além do tópico, a mensagem
enviada deve incluir o PID do processo filho que irá permitir ao Servidor identificar quais
os tópicos que foram subscritos.
vnt <número notícia>: Pedido do conteúdo de uma notícia. Em primeiro lugar, é
solicitado ao Servidor o PID do processo filho Agência que serve o pedido de conteúdo da
notícia. Recorrendo a este PID, envia uma mensagem, através da fila de mensagens 2.
Recebida a confirmação da disponibilidade da notícia, abre o pipe nomeado criado numa
subdirectoria definida pelo programa Servidor (ambas do conhecimento dos processos
comunicantes). O nome do FIFO coincide com o PID deste processo. O conteúdo da
notícia é lido do FIFO e visualizado no monitor. Terminado o processo de transferência, o
FIFO é eliminado.
s: Este comando termina o programa, devendo enviar um sinal ao processo filho para que
termine a sua execução.
Processo filho:
O processo filho aguarda por mensagens colocadas na fila 2 que dizem respeito a notificações
fornecidas pelo Servidor quando uma nova notícia é publicada num tópico que tenha sido
subscrito por este programa. A notificação de uma notícia é visualizada no monitor (tópico,
número e título).
Programa Monitor:
Para que o processo Servidor possa responder às solicitações, uma estrutura de dados deverá ser
mantida em memória. Esta memória deve ser partilhada, permitindo ao programa monitor exibir,
periodicamente (de 3 em 3 segundos), um conjunto de dados estatísticos sobre a utilização da
aplicação. Devem constar, de entre outras informações que se julguem por convenientes, o
número de notícias por tópico e o número de subscritores por tópico.
Especificações Adicionais
Em condições normais de execução, o programa Servidor deve ser colocado em execução antes
do lançamento dos programas Agência, Leitor e Monitor. Uma das suas tarefas consiste na
criação e inicialização dos mecanismos de comunicação, nomeadamente:
• memória partilhada: com o tamanho necessário para a manutenção da estrutura de dados
necessária para a aplicação;
• filas de mensagens;
• semáforos: para controlo de diversos aspectos, dos quais se destacam: a exclusão mútua no
acesso à memória partilhada; a garantia de que nunca existirão mais do que k pipes
nomeados (FIFO) em simultâneo, sendo k um valor configurável à partida.
4/5
Uma vez criados estes recursos, as respectivas identificações devem ficar disponíveis num
ficheiro de configuração (ficheiro de texto) acessível aos restantes programas que constituem esta
aplicação.
A estrutura de dados deve atender aos seguintes limites:
• Número máximo de tópicos: 10.
• Número máximo de caracteres para um tópico: 20.
• Número máximo de caracteres para um título: 50.
• Número máximo de notícias por tópico: 10.
• Número máximo de subscritores por tópico: 10.
• Número máximo de notícias que são mantidas no processo filho Agência:10.
Dada a existência destes limites, sugere-se que sejam sempre guardados os dados mais recentes.
Assim, quando, por exemplo, o número de subscritores por tópico ultrapassa o valor limite (10), é
eliminada a subscrição mais antiga. Se, por exemplo, o número de notícias por tópico for
ultrapassado, é eliminada a notícia mais antiga. Estas eliminações não devem ser comunicadas aos
restantes programas.
É assumida a possibilidade de ocorrerem algumas inconsistências. Por exemplo, o conteúdo de
uma notícia já não pode ser obtido, embora permaneça na estrutura de dados da aplicação.
Tratamento de erros
Em acréscimo ao normal controlo de erros nas aplicações, a implementação deste trabalho deverá
também contemplar o tratamento de determinadas situações de anomalia. A título indicativo,
apresentam-se alguns exemplos:
• execução dos programas Agência, Leitor e Monitor, antes de lançar o programa Servidor;
• tentativa de utilizar um recurso de IPC entretanto removido;
• permanência de chaves de IPC resultantes de execuções passadas mal sucedidas;
• erros nos pedidos feitos ao servidor (listar notícias de um tópico que não existe, subscrever
um tópico que não existe, etc);
• erros nos pedidos de conteúdos de notícias que já não podem ser servidas.
Terminação dos processos e libertação de recursos
Dada a importância associada à remoção dos recursos de comunicação, que por algum motivo
permaneçam indevidamente alocados, aconselha-se a criação de um pequeno programa auxiliar
que, quando invocado, desempenhe essa função. Durante a fase de desenvolvimento do trabalho e
tendo em atenção as considerações feitas nas aulas relativamente a este assunto, os alunos devem
vigiar sistematicamente a eliminação das chaves desnecessárias.
Qualidade do código
O código deve ser construído de forma a tornar simples não só o seu desenvolvimento como a
própria leitura/avaliação. Devem ser usados comentários (de forma coerente e consistente) de
modo a que, por um lado, se torne fácil a interpretação de passagens mais complexas e que, por
outro, se demonstre que quem escreveu as respectivas instruções está consciente da sua semântica
e implicações. Este aspecto será relevante na avaliação do trabalho.
Relatório
O relatório, que se pretende breve, deverá justificar as opções tomadas, bem como eventuais
desvios relativamente às especificações constantes deste enunciado. Devem ser identificadas as
principais dificuldades encontradas e respectivas soluções (quando não mencionadas neste
enunciado). No caso do trabalho entregue não implementar todos as especificações referidas, as
respectivas lacunas deverão necessariamente fazer parte desse relatório.
Bom trabalho!!
5/5
Download

aqui - Escola Superior de Tecnologia