c语言 setjmp和longjmp 实现协线程

来源:互联网 发布:天刀太白女捏脸数据 编辑:程序博客网 时间:2024/06/06 03:05

非局部跳转语句---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 0