2014-01-30 111 views
2

我正在研究C編程中的上下文切換,並在Internet上找到以下示例代碼。我試圖弄清楚只有makecontext()函數可以觸發一個可以執行某些操作的函數。其他功能如setcontext(),getcontext()swapcontext()用於設置上下文。上下文切換 - ucontext_t和makecontext()

makecontext()將函數及其參數附加到上下文中,該函數是否始終堅持上下文,直到更改提交給它爲止?

1 #include <stdio.h> 
    2 #include <stdlib.h> 
    3 #include <ucontext.h> 
    4 #define MEM 64000 
    5 
    6 ucontext_t T1, T2, Main; 
    7 ucontext_t a; 
    8 
    9 int fn1() 
10 { 
11 printf("this is from 1\n"); 
12 setcontext(&Main); 
13 } 
14 
15 void fn2() 
16 { 
17 printf("this is from 2\n"); 
18 setcontext(&a); 
19 printf("finished 1\n"); 
20 } 
21 
22 void start() 
23 { 
24 getcontext(&a); 
25 a.uc_link=0; 
26 a.uc_stack.ss_sp=malloc(MEM); 
27 a.uc_stack.ss_size=MEM; 
28 a.uc_stack.ss_flags=0; 
29 makecontext(&a, (void*)&fn1, 0); 
30 } 
31 
32 int main(int argc, char *argv[]) 
33 { 
34 start(); 
35 getcontext(&Main); 
36 getcontext(&T1); 
37 T1.uc_link=0; 
38 T1.uc_stack.ss_sp=malloc(MEM); 
39 T1.uc_stack.ss_size=MEM; 
40 makecontext(&T1, (void*)&fn1, 0); 
41 swapcontext(&Main, &T1); 
42 getcontext(&T2); 
43 T2.uc_link=0; 
44 T2.uc_stack.ss_sp=malloc(MEM); 
45 T2.uc_stack.ss_size=MEM; 
46 T2.uc_stack.ss_flags=0; 
47 makecontext(&T2, (void*)&fn2, 0); 
48 swapcontext(&Main, &T2); 
49 printf("completed\n"); 
50 exit(0); 
51 } 

回答

5

makecontext寫入功能信息到上下文,它會一直保留,直到它被其他東西覆蓋。 getcontext重寫了整個上下文,因此會覆蓋之前通過調用makecontext寫入的任何函數。同樣,swapcontext會完全覆蓋第一個參數指向的上下文。

其基本思想是,u_context在某個時間包含部分進程上下文的快照。它包含所有的機器寄存器,堆棧信息和信號掩碼。它不包含任何內存映射或文件描述符狀態。 u_context中的狀態正是您爲了實現線程或協程而需要操作的所有狀態。

編輯

swapcontext(&current, &another)保存在current當前上下文並切換到another。稍後,代碼(從another上下文運行)可能會切換回current(通過另一次調用swapcontext),或者它可能會切換到第三個上下文。 上下文結束時(使用makecontext返回時設置的函數),如果某個上下文由其uc_link字段指向,它將切換到該上下文。但是,如果uc_link爲NULL,那麼線程(以及只有一個線程的進程)將退出 - 其他未運行的上下文將被放棄。

+0

非常感謝您的解釋。我認爲swapcontext(&currentContext,&anotherContext)先與另一個上下文匹配,在完成之後,它將繼續完成&currentContext。這種理解不正確嗎?感謝您的回覆 – TonyGW

+0

@TonyGW - 不正確,請參閱上面的修改。 –