Em C, contexto é o estado atual de execução de um programa, incluindo registradores (pequenas áreas de armazenamento dentro da CPU, usadas para armazenar dados e instruções durante a execução de programas), variáveis e o fluxo de instruções, crucial para trocar tarefas.
A principal função é permitir a multitarefa. Isso garante que o sistema possa alternar entre processos de forma eficiente.
Aqui foi disponibilizado o arquivo contexts.c. É um demonstrativo de como contextos funcionam.
Logo no topo desse arquivo, percebemos a importação da biblioteca ucontext.h. Ela permite manipular o contexto de execução.
No trecho abaixo vemos que são criados 3 contextos, e esses 3 contextos terão a memória alocada do tamanho de STACKSIZE.
#define STACKSIZE 64 * 1024 /* tamanho de pilha das threads */ ucontext_t ContextPing, ContextPong, ContextMain;
E logo depois, as funções Ping e Pong que serão executadas em seus respectivos contextos:
void BodyPing(void *arg) { int i; printf("%s: inicio\n", (char *)arg); for (i = 0; iNa função main, é utilizado malloc para reservar as stacks, onde posteriormente são atribuidos com uc_stack.ss_sp ao contexto, e swapcontext é usado para alternar entre eles.
int main(int argc, char *argv[]) { char *stack; printf("main: inicio\n"); getcontext(&ContextPing); stack = malloc(STACKSIZE); if (stack) { ContextPing.uc_stack.ss_sp = stack; ContextPing.uc_stack.ss_size = STACKSIZE; ContextPing.uc_stack.ss_flags = 0; ContextPing.uc_link = 0; } else { perror("Erro na criação da pilha: "); exit(1); } makecontext(&ContextPing, (void *)(*BodyPing), 1, " Ping"); getcontext(&ContextPong); stack = malloc(STACKSIZE); if (stack) { ContextPong.uc_stack.ss_sp = stack; ContextPong.uc_stack.ss_size = STACKSIZE; ContextPong.uc_stack.ss_flags = 0; ContextPong.uc_link = 0; } else { perror("Erro na criação da pilha: "); exit(1); } makecontext(&ContextPong, (void *)(*BodyPong), 1, " Pong"); swapcontext(&ContextMain, &ContextPing); swapcontext(&ContextMain, &ContextPong); printf("main: fim\n"); exit(0); }Output do programa executado:
main: inicio Ping: inicio Ping: 0 Pong: inicio Pong: 0 Ping: 1 Pong: 1 Ping: 2 Pong: 2 Ping: 3 Pong: 3 Ping: fim Pong: fim main: fimCom isso, podemos perceber que mesmo alterando os contextos, os valores que "fluem" pela função são mantidos, um exemplo nesse caso é o índice do for.
Você deve ter percebido que existe um malloc para o contexto de Ping e de Pong, mas vemos que existe um contexto para main também, por qual motivo não existe um malloc para ele?
O ContextMain não precisa de uma stack separada porque ele opera na stack do thread principal, enquanto os contextos Ping e Pong têm suas próprias stacks alocadas dinamicamente.
Se crio um contexto e não aloco memória para ele, quando utilizamos o swap, ele vai para a stack principal do programa.
Esse código é do professor Maziero, encontrado no sub-projeto desenvolvido do PingPongOS "Trocas de Contexto".
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3