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 インデックスです。
ピンとポンのコンテキストに malloc があることに気づいたかもしれませんが、main にもコンテキストがあることがわかります。なぜこれに malloc がないのですか?
ContextMain はメインスレッドのスタック上で動作するため、別個のスタックを必要としませんが、Ping および Pong コンテキストには動的に割り当てられた独自のスタックがあります。
コンテキストを作成してメモリを割り当てなかった場合、スワップを使用すると、コンテキストはプログラムのメイン スタックに移動します。
このコードは Maziero 教授からのもので、PingPongOS の開発されたサブプロジェクト「Trocas de Contexto」にあります。
以上がDia e - C のコンテキストを理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。