Atenção

Blog em construção... Se tiver sugestões, serão bem vindas !!!

sábado, 20 de novembro de 2010

Processamento de trabalhos em batch

A inicialização e terminação de programas envolvia manipulações de periféricos, pelo que se pensou deixá-las a cargo de especialistas, os operadores do sistema. O utilizador deixou de ter acesso à máquina, contrariamente ao regime de máquina dedicada, atrás referido.
A figura 1 ilustra, esquematicamente, a organização dos sistemas de processamento de lotes (batch) de trabalhos.


Figure 1: Sistema de processamento batch
\begin{figure}\begin{center}
\epsfxsize =10cm
\epsfbox{batch.eps} \end{center}\end{figure}
Cada trabalho (job) podia corresponder a uma sequência de passos (job steps). Cada passo poderia envolver a compilação de um programa numa linguagem (assembly ou FORTRAN) ou a execução de um programa já compilado. O utilizador era responsável por especificar a descrição de cada trabalho, com base numa linguagem de controlo, devendo tipicamente codificar essa descrição sob a forma de cartões perfurados, editados numa máquina perfuradora de cartões. Assim, a descrição do trabalho pedido por cada utilizador constituia uma pilha de cartões, que eram depois entregues ao operador, responsável pela supervisão da execução dos trabalhos. Cartões especiais de controlo indicavam, na descrição do trabalho, informações tais como 'início de cartões de um trabalho', 'compilador de FORTRAN', 'início de sequência de cartões do programa utilizador', 'início de sequência de cartões de dados para o trabalho', etc.
O operador do sistema era responsável por escalonar a ordem segunda a qual os diversos trabalhos submetidos iriam ser executados. Uma vez decidida essa ordem, colocava as pilhas de cartões na 'calha' de leitura de um periférico de entrada: o leitor de cartões perfurados. Os cartões de cada trabalho iriam ser lidos para memória e interpretados por um programa que antes tinha sido carregado em memória (este programa era chamado monitor control program) e constituia o embrião dos actuais interpretadores de comandos do terminal (na designação anglo-saxónica shell).
Este sistema de processamento de trabalhos era estritamente sequencial, isto é, cada trabalho era executado completamente, até terminar e passar o controlo ao monitor de controlo, para este processar o próximo trabalho do lote. Durante a execução, o programa era responsável também pelas operações de entrada (leitura de cartões de dados) e de saída (escrita dos resultados numa impressora). Uma evolução introduzida nos primeiros sistemas foi a de disponibilizar as rotinas de controlo das entradas e saídas, como rotinas auxiliares, que residiam em memória, de modo a poupar o trabalho (e diminuir a probabilidade de ocorrência de erros) do programador. Estas rotinas de entrada/saída, mais o interpretador de cartões de controlo, formavam o que se designava por monitor de controlo ou programa supervisor de trabalhos. Este programa residia numa zona de memória central, conforme ilustrado na figura 2.


Figure 2: Ocupação de memória
\begin{figure}\begin{center}
\epsfbox{memoria.eps} \end{center}\end{figure}
Estes sistemas não ofereciam qualquer mecanismo de protecção contra erros imprevistos dos programas utilizadores:

  1. se o programa gerasse endereços que referissem a zona de memória do monitor, poderia corromper o seu código ou dados;
  2. o programa de um utilizador, em situações de erro, podia começar a ler os cartões de entrada, do leitor de cartões, mas correspondentes aos utilizadores seguintes, no lote de trabalhos submetidos;
  3. se o programa tivesse um ciclo infinito, nunca terminaria e o controlo nunca retornaria ao monitor de controlo, ficando o sistema completamente bloqueado
Para resolver os dois primeiros tipos de problemas, surgiram mecanismos de protecção, suportados pelo hardware dos próprios processadores (CPU). No registador de flags de estado do processador passou a haver um bit adicional de controlo, indicando o modo de operação corrente do processador.
Se este bit indicar o modo supervisor ou protegido, então todas as acções são permitidas na execução das instruções máquina, incluindo o acesso a toda a memória, sem restrições, o acesso aos registadores de controlo do processador, incluindo os que controlam o acesso às tabelas de páginas ou de segmentos dos programas, bem como o acesso às interfaces dos periféricos e o controlo do mecanismo de interrupções. Tipicamente, os programas que constituem o sistema de operação, irão ser executados no modo supervisor.
O sistema de operação, antes de passar o controlo da execução para um programa utilizador, modifica o bit de modo para indicar o modo utilizador. Neste modo, o programa só pode gerar endereços que refiram as zonas de memória às quais lhe foi dado acesso, por exemplo, através da sua tabela de páginas (inicializada pelo SO). Qualquer referência de memória fora dessas zonas é detectada pelo hardware do processador, no processo de transformação do endereço virtual, o que, em modo utilizador, origina uma interrupção do programa, por violação de memória. O mesmo controlo é exercido, de modo a impedir o programa em modo utilizador de aceder às portas de interface dos periféricos, executar instruções máquina de entrada e saída e efectuar acções de controlo do processador, por exemplo, para o controlo de interrupções. A figura 3 ilustra, esquematicamente, as acções permitidas e as proibidas.


Figure 3: Modos de operação do processador
\begin{figure}\begin{center}
\epsfbox{modos.eps} \end{center}\end{figure}
Como aquelas acções ficam proibidas e são impostas por hardware, os erros dos dois primeiros tipos podem ser controlados pelo SO.
Surge, entretanto, uma dúvida. Se, em modo utilizador, o programa não pode executar instruções de entrada e saída, como é que comunica com o exterior, isto é, recebe dados e produz resultados, envolvendo os dispositivos periféricos, sejam de entrada, de saída ou de arquivo de ficheiros? A resposta é: fazendo pedidos ao SO, através da invocação de chamadas ao sistema, conforme se explicou na primeira aula.

Nenhum comentário:

Postar um comentário