c语言 setjmp和longjmp 实现协线程

非局部跳转语句---setjmp和longjmp函数。</span>

非局部指的是,这不是由普通C语言goto,语句在一个函数内实施的跳转,而是在栈上跳过若干调用帧,返回到当前函数调用路径上的某一个函数中。

#include <setjmp.h>
Int setjmp(jmp_buf  env);
   返回值:若直接调用则返回0,若从longjmp调用返回则返回非0值
Void longjmp(jmp_buf env,int val);
    在希望返回到的位置调用setjmp,此位置在main函数中,因为直接调用该函数,所以其返回值为0.setjmp参数evn的类型是一个特殊的类型jmp_buf,这一数据类型是某种形式的数组,其中存放在调用longjmp时能用来恢复栈状态的所有信息。因为需要在另一个函数中引用env变量,所以规范的处理方式是将env变量定义为全局变量。

   当检查到一个错误时,则以两个参数调用longjmp函数,第一个就是在调用setjmp时所用的env,第二个参数是具有非0值的val,它将成为从setjmp处返回的值。使用第二个参数的原因是对于一个setjmp可以有多个longjmp


例子:

<pre name="code" class="cpp">#include <stdio.h>
#include <unistd.h>
#include <setjmp.h>
#include <stdlib.h>

typedef struct {
	void *private_data;
	void (*start)(void*);
	jmp_buf context; //上下文切换

}Context;

 static void task0(void* arg) {
		printf("task0\n");
 }

 static void task1(void* arg) {
		printf("task1\n");
 }

 static void task2(void* arg) {
		printf("task2\n");
 }

 static Context *Task;
 static int run_index=0;
 static int index=0;
 static int count = 0;

 static void run(Context* c) {

 	c->start(c->private_data);
 	count++;
 	run_index = count % index;
 	printf("run_index=%d, count=%d\n", run_index, count);
 	sleep(1);
 	longjmp(Task[run_index].context,1);
 }

 void TaskInit(int size) {
 	Task = (Context*)malloc(size * sizeof(Context));

 }

void createTask(void (*start)(void*), void* arg) {
	Task[index].start = start;
	Task[index].private_data = arg;
	if(setjmp(Task[index].context)) {
		printf("%s\n", "run" );

		run(&Task[run_index]);
		//longjmp(Task[0].context, 1);
	}
	index++;
}

void start() {
	longjmp(Task[0].context, 1);// 开始第一个任务
}
 int main() {
 

	TaskInit(2);
	createTask(task0, (void*)0);
	createTask(task1, (void*)1);
	createTask(task2, (void*)2);
	start();
 }


 

上面有个问题:明明只创建了2个任务,结果加了好几个都没报内存错误。我就奇怪了。不知道原因,有知道的请指教

 
 

 
 

上面只是简单的例子,可以用队列对不同的任务进行管理。有不足请包涵。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值