協同例程是某種類似於多線程的概念,只是線程的切換由程序自己掌控,可以避免傳統線程間切換時的數據保護問題。
這裏使用setjmp和longjmp的配合(形式上是從一個函數跳到另一個函數,實際上是返回歷史執行點),實現了比較簡陋的協同例程。
下面程序執行流程就體現了,執行流在main的while loop和aux的while loop之間跳轉,依次執行。
注:此處代碼是在Dev-CPP中編譯運行的
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
int main_stack[256];
int aux_stack[256];
jmp_buf main_jmp;
jmp_buf aux_jmp;
int *co_base = NULL; // 分離點
int *main_top = NULL;
int *aux_top = NULL;
int aux();
void co_swap_aux();
void co_swap_main();
void co_save(int stack[], int *co_top);
void co_restore(int stack[], int *co_top);
int main()
{
int base;
co_base = &base;
main_top = co_base;
co_save(main_stack, main_top);
if(!setjmp(main_jmp))
{
aux();
}
co_restore(main_stack, main_top);
while(1)
{
printf("run in main...1\n");
system("PAUSE");
co_swap_main();
printf("run in main...2\n");
system("PAUSE");
co_swap_main();
printf("run in main...3\n");
system("PAUSE");
co_swap_main();
}
return 0;
}
int aux()
{
while(1)
{
printf("run in aux....1\n");
system("PAUSE");
co_swap_aux();
printf("run in aux....2\n");
system("PAUSE");
co_swap_aux();
printf("run in aux....3\n");
system("PAUSE");
co_swap_aux();
}
return 0;
}
void co_swap_aux()
{
int top;
aux_top = ⊤
co_save(aux_stack, aux_top);
if(!setjmp(aux_jmp))
{
longjmp(main_jmp, 1);
}
co_restore(aux_stack, aux_top);
}
void co_swap_main()
{
int top;
main_top = ⊤
co_save(main_stack, main_top);
if(!setjmp(main_jmp))
{
longjmp(aux_jmp, 1);
}
co_restore(main_stack, main_top);
}
void co_save(int stack[], int *co_top)
{
size_t size = (long)co_base - (long)co_top;
memcpy(stack, co_top, size);
}
void co_restore(int stack[], int *co_top)
{
size_t size = (long)co_base - (long)co_top;
memcpy(co_top, stack, size);
}
運行界面截圖: