协同例程是某种类似于多线程的概念,只是线程的切换由程序自己掌控,可以避免传统线程间切换时的数据保护问题。
这里使用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);
}
运行界面截图: