在C语言中,上下文是程序当前的执行状态,包括寄存器(CPU内部的小存储区域,用于在程序执行过程中存储数据和指令)、变量和流程指令,对于切换任务至关重要。
主要功能是允许多任务处理。这样可以保证系统能够高效地在进程之间切换。
contexts.c 文件已在此处提供。它演示了上下文如何工作。
在此文件的顶部,我们注意到 ucontext.h 库的导入。它允许您操纵执行上下文。
在下面的摘录中,我们看到创建了 3 个上下文,这 3 个上下文将分配 STACKSIZE 大小的内存。
#define STACKSIZE 64 * 1024 /* tamanho de pilha das threads */ ucontext_t ContextPing, ContextPong, ContextMain;
不久之后,Ping 和 Pong 函数将在各自的上下文中执行:
void BodyPing(void *arg) { int i; printf("%s: inicio\n", (char *)arg); for (i = 0; i在主函数中,malloc用于保留堆栈,随后将它们通过uc_stack.ss_sp分配给上下文,而swapcontext用于在它们之间切换。
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); }执行程序的输出:
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: fim由此,我们可以看到,即使更改上下文,“流”过函数的值仍然保留,这种情况下的一个例子是 for index。
你可能已经注意到,Ping和Pong的上下文有一个malloc,但是我们看到main也有一个上下文,为什么没有一个malloc呢?
ContextMain 不需要单独的堆栈,因为它在主线程的堆栈上操作,而 Ping 和 Pong 上下文有自己的动态分配的堆栈。
如果我创建一个上下文并且不为其分配内存,当我们使用交换时,它会进入程序的主堆栈。
这段代码来自Maziero教授,在PingPongOS开发的子项目“Trocas de Contexto”中找到。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3