Notas do estudo sobre "Introdução ao sistema operacional" (1): Visão geral do sistema operacional


Esta série de artigos é principalmente as notas de estudo de "Sistemas operacionais: três peças fáceis" e seu curso de suporte CS-537 (Introdução aos sistemas operacionais) da Universidade de Wisconsin.Enquanto isso, alguns materiais fáceis de entender serão intercalados durante esse período.

Visão geral

A introdução do sistema operacional parte da essência dos três sistemas operacionais de design, como virtualidade, simultaneidade e persistência, e passa pelo gerenciamento de processos, gerenciamento de memória, gerenciamento de arquivos e gerenciamento de E / S do sistema operacional tradicional.

Virtualidade Concorrência Persistência
Gerenciamento de processos Processo, programação da CPU Encadeamento, deadlock, sincronização de processos
Gerenciamento de memória Gerenciamento de memória
Gerenciamento de armazenamento Sistema de E / S Sistema de arquivos, armazenamento grande

Por que você precisa de um sistema operacional?

Insira a descrição da imagem aqui
O sistema do computador pode ser dividido em hardware, sistema operacional, sistema e software de aplicativo de baixo para cima. Os usuários trabalham na camada de software e usam o Word, Matlab e outros softwares para atingir seus próprios objetivos: do ponto de vista do hardware, o computador é apenas o processo de busca, decodificação e execução da CPU. Portanto, como conectar razoavelmente o software do aplicativo ao hardware, isso requer a introdução do software do sistema operacional como a interface entre os dois.
Insira a descrição da imagem aqui
A essência do software do sistema operacional é um programa infinitamente cíclico.Depois da inicialização, ele continuará aceitando as instruções do usuário até que o programa seja forçado a desligar. MacOS base, Linux e outros sistemas e downloads common.htais como cabeçalhos , podemos simular o processo de execução do sistema operacional:

// cpu.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <assert.h>
#include "common.h"

int main(int argc, char *argv[])  // argc 命令行参数个数
{								  // argv 命令行参数向量
  if (argc != 2) {
    fprintf(stderr, "usage: cpu <string>\n");
    exit(1);
  }

  char *str = argv[1];
  while (1) {
    Spin(1);
    printf("%s\n", str);
  }

  return 0;
}

Função Spin (): localizada em common.h, faça com que o intervalo de saída do programa
gcc -o execute o nome do arquivo nome do arquivo fonte: compile o arquivo fonte
Wall: exiba todos os avisos após a compilação
Werror: processe todos os avisos como erros e
Insira a descrição da imagem aqui
execute o comando hello, Podemos descobrir que o programa continuará emitindo hello até que o programa seja forçado a terminar.
Insira a descrição da imagem aqui
Digite mais alguns comandos, o programa emitirá 3 comandos ao mesmo tempo, para que o usuário tenha a ilusão de que várias CPUs estão executando comandos ao mesmo tempo.Esta é a virtualização da CPU.

Virtualização

A virtualização é mapear uma entidade física em várias contrapartes lógicas, e o método de implementação é a multiplexação por divisão do tempo e multiplexagem por divisão espacial. Podemos simular a virtualização da memória e obter o número do processo através de getpid (), atualizar os dados com o ponteiro p e obter o endereço de armazenamento de dados.

// mem.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "common.h"

int main(int argc, char *argv[])
{
  if (argc != 2) {
    fprintf(stderr, "usage: mem <value>\n");
    exit(1);
  }
  
  int *p = malloc(sizeof(int));
  assert(p != NULL);                         // getpid() 进程识别码   p 指向内存的指针
  printf("(pid:%d) addr of p:        %llx\n", (int)getpid(), (unsigned long long)p);
  printf("(pid:%d) addr stored in p: %llx\n", (int)getpid(), (unsigned long long)p);
  
  *p = atoi(argv[1]); // assign value to addr stored in p
  while (1) {
    Spin(1);
    *p = *p + 1;
    printf("(pid:%d) p: %d\n", getpid(), *p);
  }
 
  return 0;
}

Insira a descrição da imagem aqui
Insira a descrição da imagem aqui
No momento, dois processos são executados em minha máquina, os números de processo são 11984 e 11985, os endereços de armazenamento são 7fbf56c01720 e 7fb86cc01720 e aumentam em 1 a cada vez de 1000 e 2000, respectivamente.

Concorrência

A simultaneidade é executar vários processos dentro do mesmo intervalo de tempo na macro.O sistema operacional implementa processos e threads.

// threads.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "common.h"

volatile int counter = 0;  // 本条指令不会因编译器的优化而省略,且要求每次直接读值。
int loops;

void *worker(void *arg) {  // 计数器
  int i;
  for (i = 0; i < loops; i++) {
    counter++;
  }
  return NULL;
}

int main(int argc, char *argv[]) {
  if (argc != 2) {
    fprintf(stderr, "usage: threads <value>\n");
    exit(1);
  }

  loops = atoi(argv[1]);
  pthread_t p1, p2;		// 声明线程id
  printf("Initial value : %d\n", counter);

  pthread_create(&p1, NULL, worker, NULL);
  pthread_create(&p2, NULL, worker, NULL);
  pthread_join(p1, NULL);
  pthread_join(p2, NULL);
  printf("Final value   : %d\n", counter);
  return 0;
}

pthread_create (): crie um thread e execute funções de thread relacionadas.
O primeiro parâmetro é um ponteiro para o identificador de segmento.
O segundo parâmetro é usado para definir atributos de encadeamento.
O terceiro parâmetro é o endereço inicial da função de execução do encadeamento.
O último parâmetro é o parâmetro da função em execução.

pthread_join (): bloqueia os recursos atuais do encadeamento / recuperação.O
primeiro parâmetro é o identificador do encadeamento.O
segundo parâmetro é um ponteiro definido pelo usuário usado para armazenar o valor de retorno do encadeamento em espera.
Insira a descrição da imagem aqui
O programa cria duas funções de contador de execução de thread (), o valor inicial é 0, o parâmetro é 1000 e o resultado é 2000. Mas quando o parâmetro é grande, o resultado pode ser menor que o valor esperado. Isso ocorre porque dois threads do contador compartilham o mesmo contador e dois threads podem pegar o contador e executá-lo ao mesmo tempo. A solução é bloquear o contador, ou seja, operação fotovoltaica.

pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;    // 全局信号量初始化
void *worker(void *arg) {
  int i;
  for (i = 0; i < loops; i++) {
    pthread_mutex_lock(&m);		// 上锁
    counter++;
    pthread_mutex_unlock(&m);	// 开锁
  }
  printf("%d\n", counter);
  pthread_exit(NULL);
}

Insira a descrição da imagem aqui

Persistência

Persistência é salvar dados transitórios (como objetos na memória) em um dispositivo de armazenamento (como um disco) que possa ser salvo permanentemente.

// io.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <fcntl.h>
#include <sys/types.h>

void dowork()
{
  int fd = open("/tmp/file", O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU);
  assert(fd >= 0);
  
  char buffer[20];
  sprintf(buffer, "hello world\n");
  int rc = write(fd, buffer, strlen(buffer));
  assert(rc == (strlen(buffer)));
  printf("wrote %d bytes\n", rc);
  
  fsync(fd);
  close(fd);
}
int main(int argc, char *argv[]) {
  dowork();
  return 0;
}

comando cat: visualizar o conteúdo do arquivo
Insira a descrição da imagem aqui

Conceito importante

Sistema operacional: controle e gerencie os recursos de hardware e software de todo o sistema do computador, controle razoavelmente o fluxo de trabalho do computador e forneça aos usuários e outros softwares interfaces e ambientes convenientes.

Simultaneidade: durante um período, existem vários programas em execução ao mesmo tempo na macro, mas em um sistema de processador único, apenas um programa pode ser executado por vez, portanto, esses programas só podem ser executados alternadamente em uma base microscópica.
Paralelismo: dois ou mais eventos ocorrem ao mesmo tempo. No nível macro, a CPU e os dispositivos de E / S são paralelos. No nível micro, a CPU executa várias instruções ao mesmo tempo. Ela precisa ser implementada com a introdução de pipeline de vários estágios ou processadores com vários núcleos.

Compartilhamento mutuamente exclusivo: apenas um único processo tem permissão para acessar recursos críticos ao mesmo tempo, e um mecanismo de sincronização é introduzido.
Multiplexagem por divisão de tempo: cada processo alterna-se com uma quantidade fixa de tempo da CPU e muda rapidamente para o próximo processo quando o tempo acabar.
Multiplexação por divisão de espaço: a memória é dividida em quadros de página de tamanho fixo, e cada processo também é dividido em páginas de tamanho fixo, que são parcialmente mapeadas na memória, e algoritmos de substituição de página são usados ​​para substituir as páginas em falta.

Assincronismo: O processo não é concluído de uma só vez, mas para e avança a uma velocidade imprevisível.

Notas do estudo "Introdução ao sistema operacional" (2): virtualização da CPU (processo)

Publicado 21 artigos originais · elogiado 8 · visitas 1495

Acho que você gosta

Origin blog.csdn.net/K_Xin/article/details/104543586
Recomendado
Clasificación