Mudança de contexto
Na computação, uma mudança de contexto é o processo de armazenar o estado de um processo ou thread, para que possa ser restaurado e retomar a execução em um ponto posterior e, em seguida, restaurar um diferente, anteriormente salvo, estado. Isso permite que vários processos compartilhem uma única unidade de processamento central (CPU) e é um recurso essencial de um sistema operacional multitarefa. Em uma CPU tradicional, cada processo - um programa em execução - utiliza os vários registradores da CPU para armazenar dados e manter o estado atual do processo em execução. No entanto, em um sistema operacional multitarefa, o sistema operacional alterna entre processos ou threads para permitir a execução de vários processos simultaneamente. Para cada switch, o sistema operacional deve salvar o estado do processo em execução no momento, seguido pelo carregamento do próximo estado do processo, que será executado na CPU. Essa sequência de operações que armazena o estado do processo em execução e o carregamento do próximo processo em execução é chamada de troca de contexto.
O significado preciso da frase "mudança de contexto" varia. Em um contexto multitarefa, refere-se ao processo de armazenar o estado do sistema para uma tarefa, de modo que essa tarefa possa ser pausada e outra tarefa retomada. Uma troca de contexto também pode ocorrer como resultado de uma interrupção, como quando uma tarefa precisa acessar o armazenamento em disco, liberando tempo da CPU para outras tarefas. Alguns sistemas operacionais também exigem uma troca de contexto para alternar entre as tarefas do modo de usuário e do modo kernel. O processo de troca de contexto pode ter um impacto negativo no desempenho do sistema.
Custo
Mudanças de contexto geralmente são computacionalmente intensivas, e muito do projeto de sistemas operacionais é otimizar o uso de trocas de contexto. Mudar de um processo para outro requer um certo tempo para fazer a administração - salvar e carregar registradores e mapas de memória, atualizar várias tabelas e listas, etc. O que realmente está envolvido em uma troca de contexto depende das arquiteturas, sistemas operacionais e o número de recursos compartilhados (threads que pertencem ao mesmo processo compartilham muitos recursos em comparação com processos não cooperativos não relacionados).
Por exemplo, no kernel Linux, a troca de contexto envolve carregar o bloco de controle de processo (PCB) correspondente armazenado na tabela PCB na pilha do kernel para recuperar informações sobre o estado do novo processo. As informações de estado da CPU, incluindo registradores, ponteiro de pilha e contador de programa, bem como informações de gerenciamento de memória, como tabelas de segmentação e tabelas de páginas (a menos que o processo antigo compartilhe a memória com o novo), são carregadas do PCB para o novo processo. Para evitar a tradução de endereço incorreta no caso dos processos anteriores e atuais usando memória diferente, o buffer lookaside de tradução (TLB) deve ser liberado. Isso afeta negativamente o desempenho porque cada referência de memória ao TLB será uma falha porque ele estará vazio após a maioria das trocas de contexto.
Além disso, a troca de contexto análogo ocorre entre threads de usuários, principalmente threads verdes, e geralmente é muito leve, salvando e restaurando o contexto mínimo. Em casos extremos, como alternar entre goroutines em Go, uma troca de contexto é equivalente a um rendimento de corrotina, que é apenas um pouco mais caro do que uma chamada de sub-rotina.
Mudança de casos
Existem três possíveis gatilhos para uma troca de contexto:
Multitarefa
Mais comumente, dentro de algum esquema de escalonamento, um processo deve ser desligado da CPU para que outro processo possa ser executado. Essa troca de contexto pode ser acionada pelo processo tornando-se inexequível, como ao aguardar a conclusão de uma operação de E/S ou sincronização. Em um sistema multitarefa preemptivo, o agendador também pode alternar processos que ainda podem ser executados. Para evitar que outros processos fiquem sem tempo de CPU, os escalonadores preventivos geralmente configuram uma interrupção do timer para disparar quando um processo excede sua fatia de tempo. Essa interrupção garante que o agendador obtenha controle para executar uma troca de contexto.
Tratamento de interrupção
Arquiteturas modernas são orientadas por interrupção. Isso significa que se a CPU solicitar dados de um disco, por exemplo, ela não precisa esperar até que a leitura termine; ele pode emitir a solicitação (para o dispositivo de E/S) e continuar com alguma outra tarefa. Terminada a leitura, a CPU pode ser interrompida (neste caso por um hardware, que envia solicitação de interrupção ao PIC) e apresentada a leitura. Para interrupções, um programa chamado manipulador de interrupção é instalado e é o manipulador de interrupção que manipula a interrupção do disco.
Quando ocorre uma interrupção, o hardware alterna automaticamente uma parte do contexto (pelo menos o suficiente para permitir que o manipulador retorne ao código interrompido). O manipulador pode salvar contexto adicional, dependendo dos detalhes dos designs de hardware e software específicos. Freqüentemente, apenas uma parte mínima do contexto é alterada para minimizar a quantidade de tempo gasto no tratamento da interrupção. O kernel não gera ou agenda um processo especial para lidar com interrupções, mas, em vez disso, o manipulador executa no contexto (geralmente parcial) estabelecido no início do tratamento da interrupção. Uma vez concluído o serviço de interrupção, o contexto em vigor antes da ocorrência da interrupção é restaurado para que o processo interrompido possa retomar a execução em seu estado adequado.
Troca de modo de usuário e kernel
Quando o sistema faz a transição entre o modo de usuário e o modo kernel, uma troca de contexto não é necessária; uma transição de modo não é por si só uma troca de contexto. No entanto, dependendo do sistema operacional, uma troca de contexto também pode ocorrer neste momento.
Etapas
O estado do processo atualmente em execução deve ser salvo para que possa ser restaurado quando reagendado para execução.
O estado do processo inclui todos os registradores que o processo pode estar usando, especialmente o contador de programa, além de quaisquer outros dados específicos do sistema operacional que possam ser necessários. Isso geralmente é armazenado em uma estrutura de dados chamada bloco de controle de processo (PCB) ou switchframe.
O PCB pode ser armazenado em uma pilha por processo na memória do kernel (em oposição à pilha de chamadas do modo de usuário) ou pode haver alguma estrutura de dados específica definida pelo sistema operacional para essas informações. Um identificador para o PCB é adicionado a uma fila de processos que estão prontos para serem executados, geralmente chamados de fila de prontos.
Como o sistema operacional efetivamente suspendeu a execução de um processo, ele pode alternar o contexto escolhendo um processo da fila pronta e restaurando seu PCB. Ao fazer isso, o contador de programa do PCB é carregado e, assim, a execução pode continuar no processo escolhido. A prioridade do processo e do encadeamento pode influenciar qual processo é escolhido na fila de prontos (ou seja, pode ser uma fila de prioridade).
Exemplo
Considerando uma operação de adição aritmética geral A = B+1. A instrução é armazenada no registrador de instrução e o contador de programa é incrementado. A e B são lidos da memória e armazenados nos registradores R1, R2, respectivamente. Nesse caso, B+1 é calculado e escrito em R1 como resposta final. Esta operação, como há leituras e gravações sequenciais e não há esperas para chamadas de função usadas, portanto, nenhuma troca/espera de contexto ocorre neste caso.
No entanto, certas instruções especiais requerem chamadas de sistema que requerem troca de contexto para processos de espera/suspensão. Um manipulador de chamada do sistema é usado para alternar o contexto para o modo kernel. Uma função display(data x) pode requerer dados x do disco e um driver de dispositivo no modo kernel, portanto, a função display() vai dormir e espera na operação READ para obter o valor de x do disco, fazendo com que o programa para esperar e uma espera pela chamada de função para a configuração liberada da instrução atual para dormir e aguardar a chamada do sistema para ativá-la. No entanto, para manter a simultaneidade, o programa precisa reexecutar o novo valor e o processo adormecido juntos novamente.
Desempenho
A própria troca de contexto tem um custo no desempenho, devido à execução do agendador de tarefas, liberações de TLB e indiretamente devido ao compartilhamento do cache da CPU entre várias tarefas. A alternância entre threads de um único processo pode ser mais rápida do que entre dois processos separados, porque os threads compartilham os mesmos mapas de memória virtual, portanto, uma liberação de TLB não é necessária.
O tempo para alternar entre dois processos separados é chamado de latência de troca de processo. O tempo para alternar entre dois threads do mesmo processo é chamado de latência de troca de thread. O tempo de quando uma interrupção de hardware é gerada até quando a interrupção é atendida é chamado de latência de interrupção.
Alternar entre dois processos em um único sistema operacional de espaço de endereço pode ser mais rápido do que alternar entre dois processos em um sistema operacional com espaços de endereço privados por processo.
Hardware x software
A troca de contexto pode ser realizada principalmente por software ou hardware. Alguns processadores, como o Intel 80386 e seus sucessores, têm suporte de hardware para trocas de contexto, fazendo uso de um segmento de dados especial designado como segmento de estado da tarefa (TSS). Uma troca de tarefa pode ser acionada explicitamente com uma instrução CALL ou JMP direcionada a um descritor TSS na tabela de descritor global. Pode ocorrer implicitamente quando uma interrupção ou exceção é acionada se houver um portão de tarefa na tabela do descritor de interrupção (IDT). Quando ocorre uma troca de tarefa, a CPU pode carregar automaticamente o novo estado do TSS.
Assim como outras tarefas executadas no hardware, seria de se esperar que isso fosse bastante rápido; no entanto, os sistemas operacionais convencionais, incluindo Windows e Linux, não usam esse recurso. Isso se deve principalmente a dois motivos:
- Comutação de contexto de hardware não salva todos os registros (apenas registros de uso geral, não registros de ponto flutuante — embora o
TSbit é automaticamente ligado noCR0control registrar, resultando em uma falha ao executar instruções de ponto flutuante e dando ao sistema operacional a oportunidade de salvar e restaurar o estado de ponto flutuante conforme necessário). - Problemas de desempenho associados, por exemplo, a comutação de contexto de software pode ser seletiva e armazenar apenas os registros que precisam armazenar, enquanto que as lojas de comutação de contexto de hardware quase todos os registros se eles são necessários ou não.
Contenido relacionado
Padrão da Internet
Rede local
Compatibilidade com versões anteriores