quarta-feira, 18 de setembro de 2013

Arquitectura

Sistemas de numeração/ Representação Numérica 

Sistema Decimal
(alfabeto de símbolos)   : 10 símbolos (0,1,2,.....,9)

Sistema Binário: 2 símbolos (0,1)

Quantidade numérica pode ser representada recorrendo a um alfabeto K símbolos 

Exemplo decimal:
base=2

2 3 5 = 2*10^2 + 2*10^1 + 2*10^0
|   |   |
|   |    unidades (posição 0)
|    dezenas  (posição 1)
centenas (posição 2)

Exemplo binário

base=2
1 1 1 0 1 = 1*2^4 + 1*2^3 + 1*2^2 + 0*2^1 + 1*2^0= 16+8+4+1=29

exercicio:
- Colocar em decimal
16        4    2    1
1 0 1 1 1= 16+4+2+1= 23







quarta-feira, 6 de março de 2013

Processos


  • Consiste num método de descrição das actividades de um sistema operativo;
  • Todo o software incluído no sistema operativo é organizado num grupo de programas executáveis. Cada um destes programas quando activo forma um processo juntamente com o ambiente de execução associado;
  • Cada processo pode "correr" num processador diferente, mas na prática é utilizada a multi-programação (cada processador "corre" vários processos), logo o sistema operativo deve fazer o escalonamento de processos de forma a ser efectuada a comutação de processos;
  • Os sistemas operativos baseados neste modelo, fornecem primitivas para a criação e destruição de processos;
  • Cada processo pode criar por sua vez processos filho independentes, podendo este continuar a sua execução concorrentemente com eles, ou então bloquear até à sua conclusão.

Contexto de um Processo

É toda a informação necessária à descrição completa do estado actual de um processo:
  • PCB (Bloco de Controlo do Processo)
    • Identificação do processo, grupo, etc;
    • Informação sobre o escalonamento: estado, prioridade, etc;
    • Localização e tamanho dos contextos de memória, de dados, de stack, ficheiros e código;
    • Registos de controlo;
    • Código;
    • Dados do programa;
    • Stack;
    • Descritores de ficheiros.

Funcionamento de Algumas System Calls

 Como funciona a função fork(), exit(),wait() ?

Fork()

fork ( int pid = fork() )

 1- Verifica se há lugar na Tabela de Processos
 2- Tenta alocar memória para o filho
 3- Altera o mapa de memória e copia para a Tabela
 4- Copia a imagem do Pai para o Filho
 5- Copia para a tabela de processos a informação do processo Pai(pid,propriedades,estado,etc)
 6- Atribui um Pid ao Pai
 7- Informa o Kernel (Núcleo do Sistema Operativo) e o sistema de ficheiros que foi criado um novo processo

Exit()

exit (exit(int estado) )

O  funcionamento depende do pai estar á espera ou não.
  * Se o pai esta á espera, então a entrada na tabela é limpa e o espaço de memória  é desalocado(o processo termina definitivamente)
 * Se o pai não está á espera, o processo fica adormecido, activando um bit na entrada correspondente da tabela, o scheduler(o responsável pelo escalonamento dos processos) recebe uma mensagem de modo a evitar o processo
 * Se o processo pai morre antes do filho fazer exit e de modo a evitar que o processo fique adormecido eternamente, este é adoptado pelo processo ttv(processo que "lê" o login) correspondente, já que este está a sempre a fazer wait
  
wait()


wait (int pid=wait(int *estado) )

Obriga o processo a esperar pelo fim de um filho de modo a libertar o espaço correspondente na tabela e originar uma eliminação definitiva.
  • Obriga a uma pesquisa da tabela de processos, para descobrir se existe algum processo filho;
  • Se existir um processo filho adormecido, ele é limpo da tabela de processos e o seu pid é retornado para o wait, assim como o argumento do exit do processo adormecido;
  • Se não houver nenhum filho adormecido, e existir algum filho no scheduler, então o processo é bloqueado até o filho executar o exit;
  • Se não existir nenhum filho na tabela de processos, o wait retorna um valor de erro.






  


quinta-feira, 20 de dezembro de 2012

Manipulação de ficheiros binários


Abertura de ficheiros binários

A abertura é feita de forma semelhante aos ficheiros de texto (no post anterior ), bastando acrescentar a letra ‘b’ ao modo de abertura.

fp = fopen("dados.txt""rb");

Operação de escrita num ficheiro binário (fwrite)

A função fwrite transfere um bloco de dados, com um determinado tamanho em bytes, da memória primária para ao ficheiro.

Protótipo: int fwrite(const void *ptr, int tamanho, int n, FILE *fp)

Onde:
ptr é um apontador para qualquer tipo de dados e irá conter o endereço de memória do bloco de dados que pretendemos escrever no ficheiro;
tamanho em bytes de cada um dos elementos que vamos escrever;
n representa o número de elementos a escrever;
fp indica(aponta) o ficheiro de dados onde pretendemos realizar a operação de escrita.

Manipulação de Ficheiros de texto


Abertura do ficheiro

Esta operação consiste em “dizer” ao programa como aceder ao ficheiro, associando-o a uma variável (fp).

Que mais tarde a variavel (fp) torna-se num apontador, que "aponta" para o ficheiro.

Para poder abri-lo também é necessário indicar o nome do ficheiro (“texto.txt”) e o modo de abertura (“r“).

fp = fopen(“texto.txt”,”r”);



Por defeito a abertura do ficheiro é realizada como se de um ficheiro de texto se tratasse ( ver ficheiros binários ).

A tabela seguinte resume as diferentes formas de abertura de ficheiros de texto em Linguagem C:





Fecho do ficheiro

Esta operação vai eliminar a ligação criada entre o programa e a variável associada ao ficheiro, garantindo que todos os dados são gravados antes de realizada esta operação.

fclose(fp);

domingo, 16 de dezembro de 2012

Ficheiros: modo de abertura

Leitura ao escrita

* r - abre o ficheiro de texto para leitura, se não existir, fopen, (..) devolve NULL

* w - Cria o ficheiro de texto para escrita. Caso já exista , esvazia-o previamente

* a - Abre o ficheiro de texto, se já existe, ou cria um novo ficheiro, se não existe, para escrita a partir  do fim do ficheiro (append)

Manipulação de ficheiros


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

main()
{
FILE *fp1, *fp2;
int contador=0;
char linha[200];
fp1 = fopen("ficheiro1.txt","r");
fp2 = fopen("ficheiro2.txt","w");

while(fgets(linha,200,fp1))
{
contador++;
if(contador%2 == 0)
{
fputs(linha,fp2);
}
}
fclose(fp1);
fclose(fp2);
}


Explicação do código


1º- Definir os apontadores para os ficheiros (fp1 e fp2);

2º- Definir a variável "linha" que vai ser usada para conter o buffer de cada linha do primeiro ficheiro.
Definir um contador, inicializando a zero. Serve para testar se as linhas lidas são pares (quando o contador é um número par) ou se são ímpares;


3º- Abrir os dois ficheiros, um para leitura e outro para escrita:

fp1 = fopen("ficheiro1.txt","r"); // ler no ficheiro


fp2 = fopen("ficheiro2.txt","w"); // escrever no ficheiro


4º- Enquanto ouver linhas para ler, é lida uma linha de cada vez do ficheiro 1

while(fgets(linha,200,fp1))

É incrementado o contador porque foi lida mais uma linha do ficheiro 1.

Se o resto da divisão inteira por 2 for zero, que significa que a linha lida é par, escrevemos essa linha no ficheiro 2


fputs(linha,fp2);

5º- Fechar os ficheiros com o fclose.