在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 < 4; i++) { printf("%s: %d\n", (char *)arg, i); swapcontext(&ContextPing, &ContextPong); } printf("%s: fim\n", (char *)arg); swapcontext(&ContextPing, &ContextMain); } /*****************************************************/ void BodyPong(void *arg) { int i; printf("%s: inicio\n", (char *)arg); for (i = 0; i < 4; i++) { printf("%s: %d\n", (char *)arg, i); swapcontext(&ContextPong, &ContextPing); } printf("%s: fim\n", (char *)arg); swapcontext(&ContextPong, &ContextMain); } /*****************************************************/
在主函数中,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 索引。
你可能已经注意到有一个用于 Ping 和 Pong 上下文的 malloc,但是我们看到也有一个用于 main 的上下文,为什么没有一个 malloc 呢?
ContextMain 不需要单独的堆栈,因为它在主线程的堆栈上操作,而 Ping 和 Pong 上下文有自己的动态分配的堆栈。
如果我创建一个上下文并且不为其分配内存,当我们使用交换时,它会进入程序的主堆栈。
此代码来自 Maziero 教授,在 PingPongOS 开发的子项目“Trocas de Contexto”中找到。
以上是Dia e - 理解 C 语言的上下文的详细内容。更多信息请关注PHP中文网其他相关文章!