使用这两个函数时,一定要牢记, longjmp函数是有去无回的,后面还有两个错误的使用示例。
#include <setjmp.h>
int setjmp(jmp_buf env);
void longjmp(jmp_buf env, int val);
基础例子:
#include <setjmp.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
int setjmp(jmp_buf env);
#define _DEBUG_INFO
#ifdef _DEBUG_INFO
#define DEBUG_INFO(format, ...) printf("%s:%s:%d $$ " format "\n" \
,__FILE__,__func__,__LINE__ \
, ##__VA_ARGS__)
#else
#define DEBUG_INFO(format, ...)
#endif
static jmp_buf env;
static void f2(){
longjmp(env,2);
}
static void f1(int argc){
if(argc == 1){
longjmp(env,1);
}else{
f2();
}
}
int main(int argc,char *argv[]){
switch (setjmp(env))
{
case 0:
DEBUG_INFO("初始化完毕,调用f1()");
f1(argc);
break;
case 1:
DEBUG_INFO("jump form f1()");
break;
case 2:
DEBUG_INFO("jump form f2()");
break;
default:
DEBUG_INFO("jump form ???");
break;
}
DEBUG_INFO("bye bye");
return 0;
}
测试时分带参数和不带参数
不带参数从f1跳回。
带参数,从f2跳回,
错误示例
下面是错误示例,仅供参考。
错误测试代码一:
#include <setjmp.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
int setjmp(jmp_buf env);
#define _DEBUG_INFO
#ifdef _DEBUG_INFO
#define DEBUG_INFO(format, ...) printf("%s:%s:%d $$ " format "\n" \
,__FILE__,__func__,__LINE__ \
, ##__VA_ARGS__)
#else
#define DEBUG_INFO(format, ...)
#endif
static jmp_buf env_01;
static jmp_buf env_02;
void func_1(){
DEBUG_INFO("longjmp env_01 start");
longjmp(env_01,1);
DEBUG_INFO("longjmp env_01 finish");
}
void func_2(){
DEBUG_INFO("longjmp env_02 start");
longjmp(env_02,2);
DEBUG_INFO("longjmp env_02 finish");
}
void* protocol_01(void *arg){
do{
switch(setjmp(env_01)){
case 0:
sleep(1);
break;
case 1:
DEBUG_INFO("01:process a");
sleep(1);
break;
case 2:
DEBUG_INFO("01:process b");
sleep(1);
break;
default:
DEBUG_INFO("01:unknown command");
break;
}
}while(1);
}
void* protocol_02(void *arg){
do{
switch(setjmp(env_02)){
case 0:
sleep(1);
break;
case 1:
DEBUG_INFO("02:process a");
sleep(1);
break;
case 2:
DEBUG_INFO("02:process b");
sleep(1);
break;
default:
DEBUG_INFO("02:unknown command");
break;
}
}while(1);
}
int main(int argc, char **argv)
{
pthread_t t1,t2;
if(pthread_create(&t1, NULL,protocol_01,&env_01) < 0){
perror("pthread_create");
return 0;
}
if(pthread_create(&t2, NULL,protocol_02,&env_02) < 0){
perror("pthread_create");
return 0;
}
pthread_detach(t1);
pthread_detach(t2);
sleep(1);
int a = 0;
while(1){
sleep(1);
a++;
if(a & 0x01){
func_1();
}else{
func_2();
}
}
return 0;
}
测试结果:
实验解析:
跳转函数是个有去无回的旅行,也就是func_1执行了以后就永远不会返回,所以,在这个例子中,调用了func_1函数后,main函数就永远不会执行了。所以这个例子还是你不行啊。
错误测试代码二:在代码一的基础上做的优化。
#include <setjmp.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
int setjmp(jmp_buf env);
#define _DEBUG_INFO
#ifdef _DEBUG_INFO
#define DEBUG_INFO(format, ...) printf("%s:%s:%d $$ " format "\n" \
,__FILE__,__func__,__LINE__ \
, ##__VA_ARGS__)
#else
#define DEBUG_INFO(format, ...)
#endif
static jmp_buf env_01;
static jmp_buf env_02;
void func_1(int arg){
DEBUG_INFO("longjmp env_01 start");
longjmp(env_01,arg);
DEBUG_INFO("longjmp env_01 finish");
}
void func_2(int arg){
DEBUG_INFO("longjmp env_02 start");
longjmp(env_02,arg);
DEBUG_INFO("longjmp env_02 finish");
}
void* protocol_01(void *arg){
do{
switch(setjmp(env_01)){
case 0:
sleep(1);
break;
case 1:
DEBUG_INFO("01:process a");
sleep(5);
func_2(1);
break;
case 2:
DEBUG_INFO("01:process b");
sleep(10);
func_2(2);
break;
default:
DEBUG_INFO("01:unknown command");
break;
}
}while(1);
}
void* protocol_02(void *arg){
do{
switch(setjmp(env_02)){
case 0:
sleep(1);
break;
case 1:
DEBUG_INFO("02:process a");
sleep(5);
func_1(2);
break;
case 2:
DEBUG_INFO("02:process b");
sleep(5);
func_1(1);
break;
default:
DEBUG_INFO("02:unknown command");
break;
}
}while(1);
}
int main(int argc, char **argv)
{
pthread_t t1,t2;
DEBUG_INFO("pid = %d",getpid());
if(pthread_create(&t1, NULL,protocol_01,&env_01) < 0){
perror("pthread_create");
return 0;
}
if(pthread_create(&t2, NULL,protocol_02,&env_02) < 0){
perror("pthread_create");
return 0;
}
pthread_detach(t1);
pthread_detach(t2);
sleep(1);
func_1(1);
return 0;
}
结果如下,代码崩溃了