setjmp和longjmp

news2024/10/4 0:25:42

使用这两个函数时,一定要牢记, 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;
}


 结果如下,代码崩溃了

 小结

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/699798.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

XHbuilder 需要的 ipa 签名,超详细的教程,你不看吃亏的是自己!

今天使用 hbuilder 运行到 ios 真机的时候&#xff0c;突然发现还需要 ipa 签名&#xff0c;这是什么东东呢&#xff1f; 1、IPA 签名是什么&#xff1f; 因苹果公司禁止企业证书用于非企业内部开发者。所以开发者无法再使用DCloud的企业证书签名的标准运行基座。 运行标准基…

预约直播 | 展心展力MetaApp:基于DeepRec的稀疏模型训练实践

MetaApp-推荐广告研发部&#xff0c;主要负责 MetaApp 拳头产品 233 乐园的首页信息流的推荐和广告系统&#xff0c;是比较传统的推广搜组。本次议题介绍了 MetaApp-推荐广告研发部 从传统的TensorFlow&#xff08;cpu&#xff09;自研分布式ps方案&#xff0c;逐步迁移到使用…

智能安全配电装置伙房食堂中的应用

【摘要】伙房食堂是高频用火用电场所&#xff0c;用火用电设备集中&#xff0c;同时人流量密集&#xff0c;如果没有做好预防工作&#xff0c;则容易引发火灾&#xff0c;造成人员伤亡。智能安全配电装置作为一种安全配电产品&#xff0c;可以有效预防电气事故的发生&#xff0…

HttpRunner_参数化进阶

目录 一.获取返回包数据 二.调用其他接口返回值 三.yml文件 四.设置全局变量并引用 五.调用函数 六.参数化驱动(最简单的方式) 七.参数化驱动(复杂的方式)   八.使用指定的报告模板指定报告生成路径 九.保存测试过程数据 十.单独使用HttpRunner 一.获取返回包数据 …

QCN6274 QCN9274 What is the difference?|WIFI7 Solution|Wallys

QCN6274 QCN9274 What is the difference?|WIFI7 Solution|Wallys Q:QCN6274 QCN9274 What is the difference? A:The QCN6274 is a Qualcomm WiFi 7 chip, and Wallys is currently in the process of developing a WiFi module integrated with the QCN9274 chip. Its imp…

Pytorch实现多GPU并行训练(DDP)

Pytorch实现并行训练通常有两个接口&#xff1a;DP&#xff08;DataParallel&#xff09;和DDP&#xff08;DistributedDataParallel&#xff09;。目前DP&#xff08;DataParallel&#xff09;已经被Pytorch官方deprecate掉了&#xff0c;原因有二&#xff1a;1&#xff0c;DP…

浅聊Android性能优化~

作者&#xff1a;一只修仙的猿 前言 关于性能优化&#xff0c;可能我们的第一反应是这是高手做的事情&#xff0c;一直以来我也是这样认为的。但在最近一段时间&#xff0c;在公司项目上做了一些框架的性能优化&#xff0c;让我初步掀开了性能优化的面纱&#xff0c;也对他有了…

VirtualBox 部署 KVM 虚拟化

什么是KVM技术&#xff1f; KVM&#xff08;Kernel-based Virtual Machine&#xff09;是一种开源的虚拟化技术&#xff0c;它是Linux内核的一部分。KVM通过将Linux内核转换为Hypervisor&#xff0c;允许在同一物理主机上运行多个虚拟机实例&#xff0c;每个实例可以独享一部分…

JAVA学习之String学习

1.底层是用什么实现的&#xff1f; JDK8用的char数组&#xff0c;JDK9开始使用byte数组,而且都是final型&#xff0c;所以不同字符串&#xff08;值&#xff09;的地址必然不同。 char和byte的区别&#xff1a;char是2个字节表示&#xff0c;而byte是一个字节。 JDK17中&…

Vue3解决:[Vue warn]: Failed to resolve component: el-table(或el-button) 的三种解决方案

1、问题描述&#xff1a; 其一、报错为&#xff1a; [Vue warn]: Failed to resolve component: el-table If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. at <App> 或者&#xff1a; …

网络安全(黑客)自学

建议一&#xff1a;黑客七个等级 黑客&#xff0c;对很多人来说充满诱惑力。很多人可以发现这门领域如同任何一门领域&#xff0c;越深入越敬畏&#xff0c;知识如海洋&#xff0c;黑客也存在一些等级&#xff0c;参考知道创宇 CEO ic&#xff08;世界顶级黑客团队 0x557 成员&…

kubectl-ai:K8S资源清单的GPT助手

琦彦&#xff0c;在 **云原生百宝箱 **公众号等你&#xff0c;与你一起探讨应用迁移&#xff0c;GitOps&#xff0c;二次开发&#xff0c;解决方案&#xff0c;CNCF生态&#xff0c;及生活况味。 kubectl-ai 项目是一个kubectl使用 OpenAI GPT 生成和应用 Kubernetes 清单的插件…

【APP自动化测试必知必会】Appium之微信小程序自动化测试

本节大纲 H5 与小程序介绍 混合 App 元素定位环境部署 混合 App 元素操作 Airtest 测试 App 01.H5与小程序介绍 H5概述 H5 是指第 5 代 HTML &#xff0c;也指用 H5 语言制作的一切数字产品。 所谓 HTML 是“超文本标记语言”的英文缩写。我们上网所看到网页&#xf…

Oculus创始人谈Vision Pro:苹果在硬件设计、营销都做对了选择

早在Vision Pro正式发布之前&#xff0c;Oculus创始人Palmer Luckey就已经体验过早期版本&#xff0c;并给出了极高的评价。Luckey指出&#xff0c;苹果在XR头显上的策略是明智的&#xff0c;先打造出每个人预期中的头显&#xff0c;然后再去考虑如何让大家买得起。 Vision Pro…

远程控制电脑软件VNC安装使用教程:Windows系统

什么是VNC&#xff1f; VNC (Virtual Network Console)&#xff0c;即虚拟网络控制台&#xff0c;它是一款基于 UNIX 和 Linux 操作系统的优秀远程控制工具软件&#xff0c;由著名的 AT&T 的欧洲研究实验室开发&#xff0c;远程控制能力强大&#xff0c;高效实用&#xff…

【python】python编程基础

基础工具包 python 原生数据结构元组 Tuple列表 list集合 set字典 dictionary NumPy 数据结构数组 Ndarray矩阵 Matrix Pandas 数据结构序列 Series &#xff08;一维&#xff09;数据框 DataFrame &#xff08;二维&#xff09; Matplotlib 数据可视化绘制饼图绘制折线图绘制直…

《Linux操作系统编程》 第六章 Linux中的进程监控: fork函数的使用,以及父子进程间的关系,掌握exec系列函数

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

一文读懂高分文章必备分析-GSEA

Gene Set Enrichment Analysis 或称 GSEA&#xff0c;是一种常用于转录组基因表达分析的数据挖掘技术&#xff0c;已经在《nature》、《Cell》、《ISME》、《Molecular Cell》、《Bioactive Materials》等高分杂志中发表多篇文章&#xff0c;涉及转录组及多组学内容。 凌恩生物…

yxcms存储型XSS至getshell 漏洞复现

为方便您的阅读&#xff0c;可点击下方蓝色字体&#xff0c;进行跳转↓↓↓ 01 环境部署02 漏洞配置03 利用方式04 修复方案 01 环境部署 &#xff08;1&#xff09;yxcms yxcms 基于 PHPMySQL 开发&#xff0c;这是一个采用轻量级 MVC 设计模式的网站管理系统。轻量级 MVC 设…

13-Cookie、Session、Token

目录 1.前置知识——HTTP协议 1.1.HTTP 的主要特点有以下 5 个&#xff1a; 1.2.HTTP 组成 1.3.为什么会有Cookie、Session、Token&#xff1f; 2.Cookie 3.Session PS&#xff1a;Cookie 和 Session 的联系与区别 4.Token 4.1.token的组成 4.2.token是如何生成的&am…