首页  >  文章  >  后端开发  >  Dia e - 理解 C 语言的上下文

Dia e - 理解 C 语言的上下文

Linda Hamilton
Linda Hamilton原创
2024-10-21 08:08:02358浏览

Dia e - Entendendo contextos em C

在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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn