这里用最简单直接的描述:这两组函数是用于实现类似vscode全局的标签跳转功能,setjmp负责埋下标签,longjmp负责标签跳转。
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
jmp_buf envbuf1;
jmp_buf envbuf2;
void func_label1()
{
int ret = setjmp(envbuf1);
printf("func label1 ret:%d.\n",ret);
}
void func_label2()
{
int ret = setjmp(envbuf2);
printf("func label2 ret:%d.\n",ret);
}
void test1()
{
printf("test1 called.\n");
longjmp(envbuf1,100);
printf("test1 never run here.\n");
}
void test2()
{
printf("test2 called.\n");
longjmp(envbuf1,200);
printf("test2 never run here.\n");
}
void test3()
{
printf("test3 called.\n");
longjmp(envbuf1,300);
printf("test3 never run here.\n");
}
void test4()
{
printf("test4 called.\n");
longjmp(envbuf2,400);
printf("test4 never run here.\n");
}
void test5()
{
printf("test5 called.\n");
longjmp(envbuf2,500);
printf("test5 never run here.\n");
}
void main()
{
printf("==========Start process======\n");
func_label1();
func_label2();
test1();//label1
test2();
test3();
test4();//label2
test5();
printf("==========End process======\n");
}
运行效果:
从这个运行结果可以清楚的看到两个标签的跳转效果!
#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 context *task_list;
static int run_index = 0;
static int index_max = 0;
static int count = 0;
static void task0(void *arg)
{
printf("task0,arg=%d\n", arg);
}
static void task1(void *arg)
{
printf("task1,arg=%d\n", arg);
}
static void task2(void *arg)
{
printf("task2,arg=%d\n", arg);
}
static void run(context *ct)
{
printf("run_index=%d, count=%d\n", run_index, ++count);
ct->start(ct->private_data);
run_index = count % index_max;
sleep(1);
longjmp(task_list[run_index].context, 1);//switch to next task
}
void task_init(int size)
{
task_list = (context *)malloc(size * sizeof(context));
}
void create_task(void (*start)(void *), void *arg)
{
task_list[index_max].start = start;
task_list[index_max].private_data = arg;
if (setjmp(task_list[index_max].context))
{
run(&task_list[run_index]);
}
index_max++; // 记录创建的任务数量
}
void task_start()
{
longjmp(task_list[0].context, 1); // 开始第一个任务
}
int main()
{
task_init(3); // thread max=3
create_task(task0, (void *)100);
create_task(task1, (void *)101);
create_task(task2, (void *)102);
task_start();
return 0;
}