18
Para que serve um sistema operacional? À medida que novos avanços foram sendo obtidos, procurando facilitar a leitura de dados e programas e a impressão de informações, as linguagens de programação passaram a ter de lidar com essas novas interfaces. Os sistemas operacionais surgiram para organizar e facilitar a interação dos programas com tape drives, leitoras de cartão e impressoras – dentre outras coisas. Para isso, os sistemas operacionais servem como uma camada intermediaria entre os programas e a máquina, organizando a forma como os dados são lidos e as informações impressas. O computador é um equipamento elaborado principalmente a partir de um conjunto de processadores e circuitos eletrônicos preparados para execução de tarefas lógicas baseadas em um conjunto de instruções fornecidas pelos usuários. Atualmente, essas instruções são fornecidas por programas específicos ou dispositivos adequados como teclado ou mouse. Nos primórdios da computação, conforme vimos, a entrada de dados era feita basicamente por meio de cartões perfurados. Pela definição anterior, bastaria o usuário ligar o computador e fornecer as instruções necessárias(disquete ou cartões) e o computador passaria a executar o que foi determinado. Por exemplo: 1)usuário deseja trabalhar com um editor de textos 2)Onde esta o editor de texto no disco? 3)Como carregar o editor de texto na memória, que está no disco? 4)Para gravar o texto digitado, onde está o espaço vazio do disco? 5)o espaço disponível em disco é suficiente? 6)Se for imprimir o texto, como enviar para impressora? 7)Como interpretar os comandos do mouse ou teclado? 8)A forma adotada por um programa para gravar os dados em disco, e aceito por outros programas?

Para Que Serve Um Sistema Operacional-threads

Embed Size (px)

Citation preview

Page 1: Para Que Serve Um Sistema Operacional-threads

Para que serve um sistema operacional?

À medida que novos avanços foram sendo obtidos, procurando facilitar a leitura de dados e programas e a impressão de informações, as linguagens de programação passaram a ter de lidar com essas novas interfaces.

Os sistemas operacionais surgiram para organizar e facilitar a interação dos programas com tape drives, leitoras de cartão e impressoras – dentre outras coisas. Para isso, os sistemas operacionais servem como uma camada intermediaria entre os programas e a máquina, organizando a forma como os dados são lidos e as informações impressas.

O computador é um equipamento elaborado principalmente a partir de um conjunto de processadores e circuitos eletrônicos preparados para execução de tarefas lógicas baseadas em um conjunto de instruções fornecidas pelos usuários. Atualmente, essas instruções são fornecidas por programas específicos ou dispositivos adequados como teclado ou mouse. Nos primórdios da computação, conforme vimos, a entrada de dados era feita basicamente por meio de cartões perfurados.

Pela definição anterior, bastaria o usuário ligar o computador e fornecer as instruções necessárias(disquete ou cartões) e o computador passaria a executar o que foi determinado.Por exemplo:

1)usuário deseja trabalhar com um editor de textos2)Onde esta o editor de texto no disco?3)Como carregar o editor de texto na memória, que está no disco?4)Para gravar o texto digitado, onde está o espaço vazio do disco?5)o espaço disponível em disco é suficiente?6)Se for imprimir o texto, como enviar para impressora?7)Como interpretar os comandos do mouse ou teclado?8)A forma adotada por um programa para gravar os dados em disco, e aceito por

outros programas?

Se cada programa executado pelo usuário tivesse de cuidar dessas tarefas básicas, sua complexidade cresceria tanto que seu desenvolvimento seria muito mais trabalhoso e demorado. O sistema operacional organiza o acesso básico dos programas às funções básicas do computador:-leitura e gravação em disco;-interpretar informações enviadas pelo teclado e mouse;-transmissão de dados para uma impressora ou uma rede local;

Dessa forma, o sistema operacional torna mais fácil tanto o desenvolvimento quanto a execução dos programas.

Page 2: Para Que Serve Um Sistema Operacional-threads

THREAD

1.IntroduçãoAté o final da década de 1970, sistemas operacionais, como Unix(Bell Labs), suportavam apenas processos com um único thread(monothread), ou seja, um processo com apenas um único programa fazendo parte do seu contexto.

Em 1979, durante o desenvolvimento do sistema operacional Toth, foi introduzido o conceito de processos lightweight(peso leve), onde o espaço de endereçamento de um processo podia ser compartilhado por vários programas.

Somente em meados de 1980, com o desenvolvimento do sistema operacional Mach, ficou clara a separação entre o conceito de processo e thread.

A partir do conceito de múltiplos threads(multhread) é possível projetar e implementar aplicações concorrentes de forma eficiente, pois um processo pode ter partes diferentes do seu código sendo executadas em paralelo.

Como os threads de um mesmo processo compartilham o mesmo espaço de endereçamento, a comunicação entre threads não envolve mecanismos lentos de intercomunicação entre processos, não prejudicando o desempenho da aplicação.

O desenvolvimento de programas que exploram os benefícios da programação multithread não é simples, introduz um novo conjunto de problemas, como a comunicação e sincronização de threads.

Atualmente, o conceito de multithread pode ser encontrado em diversos sistemas operacionais, como o Microsoft Windows 2000 e no Sun Solaris.

2.Ambiente Monothread

Um programa é uma seqüência de instruções, composta de desvios, repetições e chamadas a procedimentos e funções.

Em um ambiente monothread, um processo suporta apenas um programa no seu espaço de endereçamento.

Neste ambiente, aplicações concorrentes são implementadas com uso de múltiplos processos independentes ou subprocessos

Page 3: Para Que Serve Um Sistema Operacional-threads

Um exemplo do uso de concorrência pode ser encontrado nas aplicações com interface gráfica, como em um software de gerenciamento de e-mails, um usuário pode estar lendo e-mail, enviando e-mail, e recebendo e-mail.

O problema neste tipo de implementação é que o uso de processos no desenvolvimento de aplicações concorrentes demanda consumo de diversos recursos do sistema. Sempre que um novo processo é criado, o sistema deve alocar recursos para cada processo, consumindo tempo de processador neste trabalho. Como cada processo possui seu próprio espaço de endereçamento, a comunicação entre processos torna-se difícil e lenta. Alem disto, o compartilhamento de recursos comuns aos processos concorrentes, como memória e arquivos aberto, não é simples

São exemplos de sistemas monothread:-MSDOS-primeiras versões WINDOWS-versões antigas do UNIX

3.Ambiente Multithread

Com múltiplos threads, não existe a idéia de programas associados a processos, mas, sim, a threads.

O processo, neste ambiente, tem pelo menos um thread de execução, mas pode compartilhar o seu espaço de endereçamento com inúmeros outros threads.

Figura multithread

De forma simplificada, um thread pode ser definido como uma sub-rotina de um programa que pode ser executada de forma assíncrona, ou seja, executada paralelamente ao programa chamador.

Existe um programa principal que realiza a chamada de duas sub-rotinas(sub1 e sub2). Inicialmente, o processo é criado apenas com o thread_0 para execução do programa principal. Quando o programa chama as sub-rotina sub1 e sub2, são criados os thread_1 e thread_2, respectivamente, e executados independentemente do programa principal.

A grande vantagem no uso de threads é a possibilidade de minimizar a alocação de recursos do sistema, além de diminuir a alocação de recursos do sistema, e a criação, troca e eliminação de processos.

Threads compartilham o processador da mesma maneira que processos e passam pelas mesmas mudanças de estado(execução, espera e pronto).

Por exemplo, enquanto um thread espera por uma operação de E/S, outro thread pode ser executado.

Page 4: Para Que Serve Um Sistema Operacional-threads

Para permitir a troca de contexto entre diversos threads, cada um possui seu próprio contexto de hardware, com conteúdo de registradores , PC e SP.Quando um thread esta sendo executado, seu contexto de hardware está armazenado nos registradores do processador. No momento que o thread perde a utilização da CPU, as informações são atualizadas no seu contexto de hardware.

Dentro de um mesmo processo, threads compartilham o mesmo contexto de software e espaço de endereçamento com os demais threads, porém cada thread com seu contexto de hardware.

Threads são implementados internamente através de uma estrutura de dados chamada TCB-Thread Control Block(bloco de controle do thread), que armazena, além do contexto de hardware, mais algumas informações relacionadas exclusivamente ao thread, como prioridade, estado de execução, etc..

O uso de multithreads proporciona uma serie de benefícios. Programas com múltiplos threads são mais rápidos do que programas concorrentes implementados com múltiplos processos. Aplicações como editores de texto, planilhas, processadores de imagens, são especialmente beneficiados quando desenvolvidos com base em threads.

4. Arquitetura e Implementação de threads

O conjunto de rotinas disponíveis para que uma aplicação utilize as facilidades do threads e chamado de pacote de threads.

Existem diferentes abordagens na implementação deste pacote em um sistema operacional.

Threads podem ser oferecidos por uma biblioteca de rotinas, de 4 maneiras:- fora do núcleo do sistema operacional(modo usuário);- pelo próprio núcleo do sistema operacional(modo kernel);- por uma combinação de ambos(híbrido);- por um modelo conhecido como scheduler activations

4.1 Threads modo usuário (TMU)

São implementados pela aplicação e não pelo sistema operacional. Para isso, deve existir uma biblioteca de rotinas que possibilite à aplicação realizar tarefas como criação, eliminação, troca de mensagens entre threads e uma política de escalonamento. Neste modo, o sistema operacional não sabe da existência de múltiplos threads, sendo responsabilidade exclusiva da aplicação gerenciar os threads existentes.

Page 5: Para Que Serve Um Sistema Operacional-threads

4.2 Threads modo Kernel(TMK)

São implementados diretamente pelo núcleo do sistema operacional, através de chamadas a rotinas do sistema que oferecem todas as funções de gerenciamento e sincronização. O SO sabe da existência de cada thread e pode escalona-lo individualmente. No caso de múltiplos processadores, os threads de um mesmo processo podem ser executados simultaneamente.

4.3 Threads modo Híbrido

Combina as vantagens do TMU e TMK. Um processo pode ter vários TMK e, por sua vez, um TMK por ter vários TMU. O núcleo do SO reconhece os TMK e pode escalona-los individualmente. Um TMU pode ser executado em um TMK, em um determinado momento,e um instante seguinte pode executar outro.

4.4.Scheduler Activations(agendamento)

Os problemas apresentados no pacote de threads em modo híbrido existem devido à falta de comunicação entre os threads em modo usuário e modo kernel. O modelo ideal deveria utilizar as facilidades do pacote em modo kernel com o desempenho e flexibilidade do modo usuário.

Este pacote combina o melhor das duas arquiteturas, mas em vez de dividir os threads em modos usuário entre os de modo kernel, o núcleo troca informações com a biblioteca de threads utilizando uma estrutura de dados chamada scheduler activations

Caso um thread utilize uma chamada ao sistema que o coloque no estado de espera, não é necessário que o kernel seja ativado, bastando que a própria biblioteca em modo usuário escalone outro thread. Cada camada implementa seu escalonamento de forma independente, porém trocando informações quando necessário.

Page 6: Para Que Serve Um Sistema Operacional-threads

Sincronização e comunicação entre processos

1.Introdução

Na década de 1960, com o surgimento dos sistemas multiprogramáveis, passou a ser possível estruturar aplicações de maneira que partes diferentes do código do programa pudessem executar concorrentemente. Este tipo de aplicação, denominado aplicação concorrente, tem como base a execução cooperativa de múltiplos processos ou threads, que trabalham em uma mesma tarefa na busca de um resultado comum.

Em um sistema multiprogramável com único processador, os processos alternam sua execução segundo critérios de escalonamento estabelecidos pelo sistema operacional.

É natural que processos de uma aplicação concorrente compartilhem recursos do sistema, como arquivos, registros, dispositivos de E/S e áreas de memória. O compartilhamento de recursos entre processos pode ocasionar situações indesejáveis, capazes até de comprometer a execução das aplicações. Para evitar esse tipo de problema, os processos concorrentes devem ter suas execuções sincronizadas, a partir de mecanismos oferecidos pelo sistema operacional, com o objetivo de garantir o processamento correto do programas

2.Aplicações concorrentes

Em uma aplicação concorrente, é necessário que processos comuniquem-se entre si.Esta comunicação pode ser implementada através de diversos mecanismos, como variáveis compartilhadas na memória principal.

Temos um exemplo, onde dois processos concorrentes compartilham um buffer para trocar informações através de operação de gravação e leitura:

Um processo só poderá gravar dados no buffer caso este não esteja cheio;Um processo só poderá ler dados armazenados do buffer caso exista algum dado para ser lido;Em ambas as situações, os processos deverão aguardar até o buffer esteja pronto para as operações, seja de gravação, seja de leitura.

Os mecanismos que garantem a comunicação entre processos concorrentes e o acesso a recursos compartilhados são chamados mecanismos de sincronização.

No projeto de um SO multiprogramável, é fundamental a implementação destes mecanismos para garantir a integridade e a confiabilidade na execução de aplicações concorrentes.

Page 7: Para Que Serve Um Sistema Operacional-threads

3.Especificação de concorrência em programasExistem varias notações utilizadas para especificar a concorrência em programas, ou seja, partes de um programa que devem ser executadas concorrentemente.

A primeira notação para especificação da concorrência em um programa foram os comandos FORK e JOIN.

O exemplo a seguir apresenta a implementação da concorrência:

Program a;...FORK B;...JOIN B;..END

PROGRAM B;.......END;

O programa A começa a ser executado e, ao encontrar o comando FORK, faz com que seja criado outro processo para a execução do pgm B, concorrentemente ao programa A.

O comando JOIN permite que o programa A sincronize-se com B, ou seja, quando o pgm A encontrar o JOIN, só continuará a ser processado após o termino da execução do pgm B.

Os comandos FORK e JOIN são utilizados de forma semelhante no UNIX.

Uma das implementações mais claras e simples de expressar concorrência em um programa é a utilização dos comandos PARBEGIN e PAREND.

O comando PARBEGIN especifica que a seqüência de comandos seja executada concorrentemente em ordem imprevisível, através da criação de um processo para cada comando.

O comando PAREND define um ponto de sincronização, onde o processamento só continuará quando todos os processos ou threads criados já estiverem terminado suas execuções.

Page 8: Para Que Serve Um Sistema Operacional-threads

Um exemplo a seguir:

PROGRAM expressão; Var x, t1,t2,t3:real;Begin PARBEGIN T1:=SQRT(1024); T2:=35.4 * 0.23; T3:=302/7; PAREND; X:=T1+T2-T3;WRITELN(‘X=’,X);END.

Page 9: Para Que Serve Um Sistema Operacional-threads

4.Problemas de Compartilhamento de Recursos

A primeira situação envolve o compartilhamento de um arquivo em disco:O programa contacorrente:

PROGRAM CONTA_CORRENTE;..READ(ARQ, REG_CLIENTE);READLN(VALOR_DEPOSITO);REG_CLIENTE.SALDO:=REG_CLIENTE.SALDO+VALOR_DEPOSITO;WRITE(ARQ,REG_CLIENTE);..

END.

Considerando processos concorrentes pertencentes a dois funcionarios do banco que atualizam o saldo de um mesmo cliente simultaneamente.

O processo do primeiro funcionário lê o registro do cliente e soma ao campo saldo o valor do débito.

Antes de gravar o novo saldo no arquivo, o processo do segundo funcionário lê o registro do mesmo cliente, que esta sendo atualizado, para realizar outro lançamento, desta vez de crédito.

Independente de qual dos processos atualize primeiro o saldo no arquivo, o dado gravado estará inconsistente.

caixa comando saldo Valor deposito Saldo memória1 Read 1000 * 10001 Readln 1000 -200 10001 := 1000 -200 8002 Read 1000 * 10002 Readln 1000 +300 10002 := 1000 +300 13001 Write 800 -200 8002 Write 1300 +300 1300

Page 10: Para Que Serve Um Sistema Operacional-threads

5.EXCLUSAO MÚTUA

A solução mais simples para evitar os problemas de compartilhamento apresentados no item anterior é impedir que dois ou mais processos acessem um mesmo recurso simultaneamente. Para isso, enquanto um processo estiver acessando determinado recurso, todos os demais processos que queiram acessá-lo deverão esperar pelo termino da utilização do recurso. Essa idéia de exclusividade de acesso é chamada exclusão mutua.

Considere um sistema com muitos terminais em tempo compartilhado. Assuma que os usuários terminam cada linha de texto que eles digitam com a tecla <ENTER>. Suponha que seja desejável monitorar continuamente o número total de linhas que os usuários entraram no sistema desde o início do dia. Assuma que cada terminal de usuário seja monitorado por um processo diferente. Toda vez que um destes processos recebe uma linha do terminal, ele incrementa de 1 uma variável global compartilhada do sistema, chamada LINHAS. Considere o que aconteceria se dois processos tentassem incrementar LINHAS simultaneamente. Assuma que cada processo possui sua própria cópia do seguinte código:LOAD LINHAS ; Lê a variável linhas no registrador acumuladorADD 1 ; Incrementa o registrador acumuladorSTORE LINHAS ; Armazena o conteúdo do acumulador na variável

Suponhamos que LINHAS tenha o valor atual 21687. Agora suponhamos que o primeiro processo execute as instruções LOAD e ADD, deixando então o valor 21688 no acumulador. Então o processo perde o processador (após o término de seu quantum) para o segundo processo. O segundo processo então executa as três instruções, fazendo com que a variável linhas tenha o valor 21688. Ele então perde o processador para o primeiro processo que continua executando de onde tinha parado, e portanto executando a instrução STORE, e armazenando 21688 na variável LINHAS. Devido à falta de comunicação entre os processos, o sistema deixou de contar uma linha — o valor correto seria 21689.

O problema está em dois ou mais processos escreverem em uma variável compartilhada. Várias processos poderiam estar lendo uma variável compartilhada sem problemas. Entretanto, quando um processo lê uma variável que outro processo está escrevendo, ou quando um processo tenta escrever em uma variável que outro processo também esteja escrevendo, resultados inesperados podem acontecer.

O problema pode ser resolvido dando a cada processo acesso exclusivo à variável LINHAS. Enquanto um processo incrementa a variável, todos os outros processos desejando fazê-lo no mesmo instante deverão esperar; quando o primeiro processo terminar o acesso à variável compartilhada, um dos processos passa a ter acesso à variável. Assim, cada processo acessando a variável exclui todos outros de fazê-lo simultaneamente. Isto é chamado de exclusão mútua. Como veremos, os processos em espera deverão ser gerenciados de forma a esperarem um tempo razoavelmente curto.

Page 11: Para Que Serve Um Sistema Operacional-threads

5.1.Regiões Críticas

A exclusão mútua deve afetar apenas os processos concorrentes somente quando um deles estiver fazendo acesso ao recurso compartilhado. A parte do código do programa onde é feito o acesso ao recurso compartilhado é denominada região critica. Se for possível evitar que dois processos entrem mutuamente exclusiva das regiões criticas, os problemas decorrentes do compartilhamento serão evitados.

A exclusão mútua somente precisa estar presente nos instantes em que os processos acessam dados compartilhados modificáveis — quando os processos estão executando operações que não conflitam um com o outro, eles deveriam ser liberados para processarem concorrentemente. Quando um processo está acessando dados compartilhados modificáveis, é dito que o processo está em sua região crítica ou seção crítica.

Fica claro, que para evitarmos problemas como o mostrando acima, é necessário garantir que quando um processo está em sua região crítica, todos os outros processos (pelo menos aqueles que acessam a mesma variável compartilhada modificável) sejam excluídos de suas respectivas regiões críticas.

Enquanto um processo está em sua região crítica, outros processos podem certamente continuar sua execução fora de suas regiões críticas. Quando um processo deixa sua região crítica, um dos processos esperando para entrar em sua própria região crítica pode prosseguir. Garantir a exclusão mútua é um dos principais problemas em programação concorrente. Muitas soluções foram propostas: algumas baseadas em software e outras baseadas em hardware; algumas em baixo nível, outras em alto nível; algumas requerendo cooperação voluntária entre processos, outras exigindo uma rígida aderência a protocolos estritos.

Um processo dentro de uma região crítica está em um estado muito especial. O processo possui acesso exclusivo aos dados compartilhados modificáveis, e todos os outros processos desejando acessá-los devem esperar. Assim, regiões críticas devem executar o mais rápido possível, um processo não deve passar para o estado bloqueado dentro da região crítica, e regiões críticas devem ser cuidadosamente codificadas (para evitar, por exemplo, loops infinitos).

5.2.Soluções de hardware

A exclusão mutúa pode ser implementada através de mecanismos de hardware. Neste item são apresentadas as soluções de desabilitarão de interrupções e instruções test-and-set.

Page 12: Para Que Serve Um Sistema Operacional-threads

Instrução test-and-set

Muitos processadores possuem uma instrução de maquina especial que permite ler uma variável, armazenar seu conteúdo em uma outra área e atribuir um novo valor a mesma variável. Dessa forma, é garantido que dois processos não manipulem uma variável compartilhada ao mesmo tempo, possibilitando a implementação da exclusão mútua.

A instrução test-and-set possui o seguinte formato:

Quando executada o valor lógico da variável Y é copiado para X, sendo atribuído a variável Y o valor lógico verdadeiro.

Test-and-set(x,y);