在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 index。
你可能已經注意到,Ping和Pong的上下文有一個malloc,但是我們看到main也有一個上下文,為什麼沒有一個malloc呢?
ContextMain 不需要單獨的堆疊,因為它在主執行緒的堆疊上操作,而 Ping 和 Pong 上下文有自己的動態分配的堆疊。
如果我創建一個上下文並且不為其分配內存,當我們使用交換時,它會進入程式的主堆疊。
這段程式碼來自Maziero教授,在PingPongOS開發的子專案「Trocas de Contexto」中找到。
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3