協同例程使用setjmp實現

協同例程是某種類似於多線程的概念,只是線程的切換由程序自己掌控,可以避免傳統線程間切換時的數據保護問題。

這裏使用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 = &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 = &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);
}

運行界面截圖:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章