首頁  >  文章  >  後端開發  >  Dia e - 理解 C 語言的上下文

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

Linda Hamilton
Linda Hamilton原創
2024-10-21 08:08:02365瀏覽

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