[Linux] Von Neumann Arquitetura && Sistema Operacional && Conceito de Processo

Índice

1. Arquitetura Von Neumann

2. Sistema operacional

 1. Conceito

 2. O propósito de projetar o sistema operacional

3. Processo

 1. Conceitos básicos

 2. Descreva o processo-PCB

 3. Processo de organização

 4. Veja o processo e finalize

 5. Obtenha o identificador do processo através da chamada do sistema

 6. Crie um processo por meio de uma chamada de sistema - fork

 7. Status do processo

 8. Processo especial

   8.1 Processo Zumbi

   8.2 Processos Órfãos

 


1. Arquitetura Von Neumann

Nossos computadores comuns, como notebooks. A maioria de nossos computadores incomuns, como servidores, obedece ao sistema von Neumann.

O seguinte é um diagrama da arquitetura von Neumann:

  Os computadores que conhecemos são compostos de dispositivos de entrada , memória , unidades aritméticas , controladores e dispositivos de saída .

  • Unidade de entrada: incluindo teclado, mouse, scanner, tablet, placa de rede, disco, etc.;
  • Unidade Central de Processamento (CPU): Contém calculadoras e controladores, etc.;
  • Unidade de saída: display, placa de rede, impressora, etc.

  Alguns pontos devem ser enfatizados sobre von Neumann:

  • O armazenamento aqui se refere à memória;
  • Independentemente da situação do cache, a CPU aqui pode e só pode ler e escrever na memória, e não pode acessar periféricos (dispositivos de entrada ou saída);
  • Periféricos (dispositivos de entrada ou saída) só podem ser gravados ou lidos da memória se quiserem entrada ou saída de dados;
  • Em uma palavra, todos os dispositivos só podem lidar diretamente com a memória .

  Nossos dados precisam ser carregados do disco para a memória primeiro, depois lidos e calculados pela CPU, carregar os resultados calculados na memória novamente e, finalmente, gravar os dados no disco a partir da memória e nos fornecer os dados por meio de o dispositivo de saída.

  Por que a CPU não pode acessar diretamente os periféricos?

  Como os dispositivos de entrada e saída são chamados de periféricos, os periféricos geralmente são muito lentos, como discos, em comparação com a memória, sua velocidade é muito lenta, mas a velocidade de cálculo da CPU é realmente muito rápida. É como se a velocidade de leitura do disco fosse muito lenta, mas a velocidade de cálculo da CPU fosse muito rápida, mas a velocidade geral ainda fosse dominada pela velocidade de leitura do disco, então a eficiência geral seria dominada pelo lado de fora.

  O entendimento de von Neumann não deve parar no conceito, mas ir fundo na compreensão do fluxo de dados do software. Por favor, explique, a partir do momento que você entrar no QQ e começar a conversar com um amigo, o processo de fluxo de dados. Desde o momento em que você abre a janela, começa a enviar uma mensagem para ele, até o processo de fluxo de dados após ele receber a mensagem. E se o arquivo for enviado em qq?

   Primeiro leia as informações do teclado e carregue-as na memória , depois envie os dados da memória para o dispositivo de saída (placa de rede) por meio de uma série de operações e, em seguida, envie os dados para o dispositivo de entrada do amigo (placa de rede) por meio de uma série de operações de rede, o computador do amigo lê os dados do dispositivo de entrada para a memória e, em seguida, envia as informações para o computador do amigo através do dispositivo de saída (display).

2. Sistema operacional

 1. Conceito

  Qualquer sistema de computador contém uma coleção básica de programas chamados de sistema operacional (SO). De um modo geral, o sistema operacional inclui:

  • Kernel (gerenciamento de processos, gerenciamento de memória, gerenciamento de arquivos, gerenciamento de drivers);
  • Outros programas (como bibliotecas de funções, programas shell, etc.).

  Um sistema operacional é um software que gerencia recursos de hardware e software. Por que o sistema operacional gerencia software e hardware?

  Porque o sistema operacional precisa gerenciar bem os recursos de software e hardware e precisa fornecer aos usuários um bom ambiente de execução (seguro, estável, eficiente, rico em recursos, etc.).

 A essência do gerenciamento do sistema operacional : primeiro descreva, depois organize .

  • Descrição: descreve vários dados através da estrutura struct ;
  • Organização : Organize e gerencie dados por meio de estruturas de dados eficientes, como listas encadeadas.

  Em um computador, o sistema operacional é equivalente ao nosso gerenciador , o driver de hardware é equivalente ao nosso executor e o software é o nosso gerenciado .

  Em primeiro lugar, o sistema operacional não confia em ninguém ... Assim como somos usuários do banco, costumamos ir ao banco para economizar dinheiro, mas os bancos confiam em nós? Para evitar a destruição maliciosa por alguns dos usuários e causar danos ao sistema operacional, o sistema operacional não expõe todas as suas funções, mas usa chamadas de sistema para acessar o sistema operacional. Como o custo do uso de chamadas do sistema pode ser alto, algumas pessoas realizaram o desenvolvimento de software secundário com base nisso, resultando em uma  interface gráfica  , shell e conjunto de ferramentas .

   Chamadas de sistema e funções de biblioteca 

  • Do ponto de vista do desenvolvimento, o sistema operacional aparecerá como um todo para o mundo externo, mas exporá parte de sua interface para o desenvolvimento de nível superior.Essa parte da interface fornecida pelo sistema operacional é chamada de chamada de sistema;
  • No uso de chamadas do sistema, as funções são relativamente básicas e os requisitos para os usuários são relativamente altos. Portanto, os desenvolvedores interessados ​​podem encapsular adequadamente algumas chamadas do sistema para formar uma biblioteca. Com uma biblioteca, é muito benéfico para usuários de nível superior ou Desenvolvedores realizam desenvolvimento secundário.

 2. O propósito de projetar o sistema operacional

  • Interagir com o hardware e gerir todos os recursos de hardware e software;
  • Fornecer um bom ambiente de execução para programas de usuário (aplicativos).

  A estrutura do sistema de computador é em camadas e geralmente não é possível pular uma determinada camada

3. Processo

 1. Conceitos básicos

  • Conceitos de livros didáticos: uma instância de execução de um programa, um programa sendo executado, etc.;
  • Ponto de vista do kernel: atua como a entidade que aloca recursos do sistema (tempo de CPU, memória).

 Quando abrimos o gerenciador de tarefas, descobrimos que esses arquivos executáveis ​​em execução são todos processos.

 2. Descreva o processo-PCB

  • As informações do processo são colocadas em uma estrutura de dados denominada bloco de controle do processo , que pode ser entendida como uma coleção de atributos do processo ;
  • O livro chama-se PCB (bloco de controle de processo), e o PCB no sistema operacional Linux é: task_struct

 Um tipo de task_struct-PCB

  • A estrutura que descreve o processo no Linux é chamada task_struct;
  • task_struct é uma estrutura de dados do kernel do Linux que é carregada na RAM (memória) e contém informações do processo.

  Quando o sistema operacional primeiro descreve nosso processo e depois o organiza, ele primeiro cria uma estrutura com os atributos comuns de nosso programa e, em seguida, cria um objeto de estrutura para cada um de nossos processos.Este é o processo descrito primeiro. Em seguida, nosso sistema operacional usará estruturas de dados características (como listas encadeadas) para organizar nossos objetos de estrutura, que é o processo de pós-organização. Em seguida, o gerenciamento de processos do nosso sistema operacional será convertido no gerenciamento de estruturas de dados específicas.

   Portanto, processo = estrutura de dados do kernel relacionada ao processo + código e dados do processo atual.

 task_ struct classificação de conteúdo

  • Identificador: Descreva o identificador único deste processo, que é utilizado para distinguir outros processos;
  • Status: status da tarefa, código de saída, sinal de saída, etc.;
  • Prioridade: Prioridade em relação a outros processos;
  • Contador de programa: endereço da próxima instrução a ser executada no programa;
  • Ponteiros de memória: incluindo ponteiros para código de programa e dados relacionados ao processo, bem como ponteiros para blocos de memória compartilhados com outros processos;
  • Dados de contexto: os dados nos registradores do processador quando o processo é executado [exemplo de suspensão de estudos, adicionar fotos de CPU, registradores];
  • Informações de status de I/O: incluindo solicitações de I/O exibidas, dispositivos de I/O alocados para o processo e uma lista de arquivos usados ​​pelo processo;
  • Informações de cobrança: podem incluir a soma do tempo do processador, soma dos relógios usados, limite de tempo, número da conta de cobrança, etc.;
  • outra informação.

 3. Processo de organização

Ele pode ser encontrado no código-fonte do kernel. Todos os processos em execução no sistema são armazenados no kernel na forma de lista encadeada task_struct.

 4. Veja o processo e finalize

Para visualizar as informações básicas de um processo, podemos usar o comando ps -axj para listar as informações do processo usadas pelo sistema atual;

Primeiro teste um pedaço de código:

#include<stdio.h>  
#include<unistd.h>
int main()
{
   while(1)
   {
       printf("我是一个进程!\n");
       sleep(1);
   }
   return 0;
} 

Digite o comando para visualizar o processo, conforme a seguir: 

Digite ps -axj | head -1 && ps -axj | grep "test" para obter o cabeçalho e o processo com teste.

  Aqui também precisamos explicar um conceito que é o conceito de PID e PPID, que se refere ao número de identificação do processo no sistema operacional, ou seja, o identificador do processo . Sempre que um programa é aberto no sistema operacional, um ID de processo, ou PID, é criado. Obviamente, PPID é o número de identificação do processo pai.

  matar processo

Existem dois métodos: o primeiro é Ctrl + c para encerrar o processo à força e o segundo é: na forma de comando, kill -9 PID, especifique o processo de destino a ser encerrado.

  Aqui eu recomendo usar o segundo método.

 5. Obtenha o identificador do processo através da chamada do sistema

  • ID do processo (PID);
  • ID do processo pai (PPID).
#include<iostream>
#include<sys/types.h>
#include<unistd.h>
using namespace std;

int main()
{
	pid_t t = fork();
	if (t == 0)
	{
		while (1)
		{
			cout << "我是一个子进程" << " pid:" << getpid() << " ppid:" << getppid() << endl;
			sleep(1);
		}
	}
	else if (t > 0)
	{
		while (1)
		{
			cout << "我是一个父进程" << " pid:" << getpid() << " ppid:" << getppid() << endl;
			sleep(1);
		}
	}
	return 0;
}

 6. Crie um processo por meio de uma chamada de sistema - fork

  • Execute man fork para saber fork;
  • fork tem dois valores de retorno;
  • Compartilhamento de código de processo pai-filho, cada um abre espaço para dados, uma cópia privada (usando copy-on-write);
  • Após a bifurcação, if geralmente é usado para ramificação.

  Você pode ver que a função fork() é muito especial. Depois de criar com sucesso um processo filho, existem dois valores de retorno. Ela retorna o pid do processo filho para o processo pai, retorna 0 para o processo filho e retorna - 1 se a criação falhar. 

  Como entender os dois valores de retorno

Quando fork() quiser retornar o valor, de fato, o trabalho de criação de um processo filho dentro da função foi concluído. Neste momento, já existem dois processos e os dois processos continuam a executar a seguinte instrução. Após a execução fork(), naturalmente Haverá um valor de retorno, então parece-nos que existem dois valores de retorno. Na verdade, quando recebemos o valor de retorno, acionamos o copy-on-write (cópia realista é quando a operação sistema detecta que o processo filho tem uma operação de gravação. O sistema operacional alocará o espaço físico correspondente ao processo filho), e os rets aparentemente idênticos são realmente armazenados em espaços diferentes.

 7. Status do processo

  • R running status (em execução): Não significa que o processo deve estar em execução, indica que o processo está em execução ou na fila de execução;
  • S sleep state (dormindo): significa que o processo está aguardando a conclusão do evento (dormir aqui às vezes é chamado de suspensão interrompível (sono interrompível));
  • O estado de sono do disco D (sono do disco) às vezes é chamado de estado de sono ininterrupto (sono ininterrupto), o processo nesse estado geralmente aguarda o final do IO;
  • T stop state (stopped): Um processo pode ser parado (T) enviando um sinal SIGSTOP para o processo. O processo suspenso pode ser retomado enviando o sinal SIGCONT;
  • X dead state (morto): Este estado é apenas um estado de retorno, você não verá este estado na lista de tarefas.

O comando ps -axj é para visualizar as informações do processo

  (1) R running status (em execução): Não significa que o processo deve estar em execução, indica que o processo está em execução ou na fila de execução; 

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
	while (1)
	{
		;
	}
	return 0;
}

Ao executar, verifique se o status do processo é R+, indicando que está em execução.

 O que significa o sinal de + depois dele?

Aqui + significa que o processo está sendo executado em primeiro plano. Quando usamos ctrl+c, o processo pode ser encerrado. Se não escrevermos +, significa que o processo está sendo executado em segundo plano. Neste momento, ctrl+c não é possível encerrar o programa. Use o comando kill process para encerrar.

  (2) S sleep state (dormindo): significa que o processo está aguardando a conclusão do evento (dormir aqui às vezes é chamado de sono interrompível (sono interrompível));

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main()
{
	int n = 0;
	scanf("%d", &n);
	return 0;
}

Ao executar, verifique se o estado do processo é S+, indicando que está em estado de suspensão.

 (3) Estado de parada T (parado): O processo (T) pode ser interrompido enviando um sinal SIGSTOP para o processo. O processo suspenso pode ser retomado enviando o sinal SIGCONT;

kill -l: Todos os sinais podem ser exibidos, e o sinal SIGSTOP corresponde a 19 e o sinal SIGCONT corresponde a 18.

Quando entrarmos em kill -19 PID, o processo será interrompido.

Quando entrarmos em kill -18 PID, o processo será restaurado.

  (4) Estado de morte: Este estado é apenas um estado de retorno, e é instantâneo.Você pode não ver este estado na lista de tarefas, porque um processo se tornará um processo zumbi depois que morrer.

  (5) Estado zumbi: o estado após a morte do processo. Após a morte de um processo, ele estará no estado zumbi. Se seu processo pai não reciclar, ele sempre ocupará recursos e causará vazamentos de memória.

 8. Processo especial

   8.1 Processo Zumbi

  • O estado de zumbi (zumbis) é um estado especial. Um processo zumbi é criado quando um processo sai e o processo pai (usando a chamada de sistema wait()) não lê o código de retorno da saída do processo filho.
  • Um processo zumbi permanecerá na tabela de processos em um estado encerrado e continuará esperando que o processo pai leia o código de status de saída.
  • Enquanto o processo filho sair, o processo pai ainda está em execução, mas o processo pai não lê o estado do processo filho e o processo filho entra no estado Z

Vamos demonstrar o processo zumbi:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>

int main()
{
	pid_t id = fork();
	if (id == 0)
	{
		//子进程
		while (1)
		{
			printf("我是子进程,我的pid :%d,我的ppid: %d\n", getpid(), getppid());
			sleep(1);

		}
	}
	else if (id > 0)
	{
		//父进程
		while (1)
		{
			printf("我是父进程,我的pid :%d,我的ppid: %d\n", getpid(), getppid());
			sleep(1);
		}
	}
	else
	{
		perror("fail");
		exit(-1);
	}
	return 0;
}

Ao executar, use kill -9 PID para matar o processo filho no meio, e o processo filho é um processo zumbi neste momento.

   8.2 Processos Órfãos

  • Se o processo pai sair mais cedo, o processo filho sairá mais tarde e entrará em Z, o que devo fazer?
  • O processo pai sai primeiro e o processo filho é chamado de "processo órfão"
  • O processo órfão é adotado pelo processo init nº 1 e, claro, o processo init deve ser reciclado.

 Observe o trecho de código a seguir, ou seja, o processo pai é executado por 3 segundos e depois sai.Nesse momento, o processo filho é um processo órfão.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
	pid_t id = fork();
	if (id < 0) 
    {
		perror("fail");
		return 1;
	}
	else if (id == 0) 
	{
		//子进程
		printf("I am child, pid : %d\n", getpid());
		sleep(10);
	}
	else 
	{
		//父进程
		printf("I am parent, pid: %d\n", getpid());
		sleep(3);
		exit(-1);
	}
	return 0;
}

Comparação dos resultados da corrida:

 


 

Se houver deficiências neste artigo, sinta-se à vontade para comentar abaixo e corrigirei o mais rápido possível.

Ferros velhos, lembre-se de curtir e prestar atenção!!!   

Acho que você gosta

Origin blog.csdn.net/m0_63198468/article/details/131295936
Recomendado
Clasificación