「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > Dia e - C のコンテキストを理解する

Dia e - C のコンテキストを理解する

2024 年 10 月 31 日公開
ブラウズ:498

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 



メイン関数では、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 インデックスです。

ピンとポンのコンテキストに malloc があることに気づいたかもしれませんが、main にもコンテキストがあることがわかります。なぜこれに malloc がないのですか?

ContextMain はメイン スレッドのスタックで動作するため、別個のスタックを必要としませんが、Ping および Pong コンテキストには動的に割り当てられた独自のスタックがあります。

コンテキストを作成してメモリを割り当てなかった場合、スワップを使用すると、コンテキストはプログラムのメイン スタックに移動します。

このコードは Maziero 教授からのもので、PingPongOS の開発されたサブプロジェクト「Trocas de Contexto」内にあります。

リリースステートメント この記事は次の場所に転載されています: https://dev.to/matheusgb/dia-21-e-21-entendendo-contextos-em-c-2imm 侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3