彻底搞懂pthread_cleanup_push:实现载体线程安全资源释放的底层逻辑

GPS Android底层驱动架构解析:从NMEA到HAL的完整调试指南 在嵌入式系统与Android系统集成中,GPS定位功能依赖一条从硬件芯片到应用框架的完整数据链路。理解其底层驱动架构是优化定位性能的前提。通常,GNSS芯片通过串口输出NMEA 0183协议文本,内核驱动负责字节流传输,硬件抽象层(HAL)通过GpsInterface接口与Android框架交互,最终通过JNI回调上抛位置信息。这套分层机制决定了问题定位方向:没有数据先查串口与设备树,有数据不定位再看HAL与天线射频。本文结合源码梳理了GPS Android底层驱动的框架、移植步骤与常见调试坑,帮助嵌入式开 阅读详情

第一章:彻底理解pthread_cleanup_push的核心作用

在多线程编程中,资源的正确释放是确保程序稳定运行的关键。`pthread_cleanup_push` 是 POSIX 线程库提供的重要机制,用于注册在线程异常退出或被取消时自动执行的清理函数。

清理函数的注册与触发时机

当线程调用 `pthread_exit()`、被其他线程取消(`pthread_cancel`),或通过 `pthread_cleanup_pop(1)` 弹出并执行时,注册的清理函数将按后进先出(LIFO)顺序调用。这保证了资源如互斥锁、动态内存等能被安全释放。
  • 清理函数由 `pthread_cleanup_push` 压入栈中
  • 必须与 `pthread_cleanup_pop` 成对出现,避免编译错误
  • 传递给该宏的函数需符合 `void (*routine)(void *)` 类型

基本使用示例


#include <pthread.h>
#include <stdio.h>

void cleanup_handler(void *arg) {
    printf("清理资源: %s\n", (char*)arg);
}

void* thread_func(void *arg) {
    pthread_cleanup_push(cleanup_handler, "互斥锁释放");
    pthread_cleanup_push(cleanup_handler, "内存释放");

    // 模拟工作
    pthread_cleanup_pop(0); // 弹出但不执行
    pthread_cleanup_pop(1); // 弹出并执行

    return NULL;
}

上述代码中,两个清理函数被依次压入栈。第二次调用 pthread_cleanup_pop(1) 会触发“内存释放”的处理函数。注意:即使未显式调用 pthread_exit,只要结构匹配,宏机制就能正常展开。

典型应用场景对比

场景是否需要清理推荐方式
线程自然返回否手动释放资源
调用 pthread_exit是pthread_cleanup_push
被 pthread_cancel 中断是必须使用清理栈

graph TD
    A[线程开始] --> B[调用pthread_cleanup_push]
    B --> C[执行关键操作]
    C --> D{是否被取消?}
    D -- 是 --> E[自动执行清理函数]
    D -- 否 --> F[调用pthread_cleanup_pop]
    F --> G[根据参数决定是否执行清理]

第二章:pthread_cleanup_push的底层机制解析

2.1 清理函数栈的结构与线程私有存储

在多线程运行时环境中,每个线程拥有独立的执行栈和私有存储空间(Thread Local Storage, TLS),用于维护函数调用上下文与局部状态。清理函数栈不仅涉及返回地址与局部变量的释放,还需正确处理线程退出时TLS资源的回收。
栈帧结构布局
典型的栈帧包含返回地址、前一帧指针、局部变量与参数副本。函数返回时,通过恢复帧指针与栈指针完成清理。

push %rbp
mov  %rsp, %rbp
sub  $16, %rsp        # 分配局部变量空间
...
mov  %rbp, %rsp
pop  %rbp              # 恢复现场
ret
上述汇编序列展示了标准的函数进入与退出流程,ret指令弹出返回地址并跳转,自动完成栈顶清理。
线程私有存储管理
TLS变量在加载时由运行时系统分配独立内存区域,线程终止时需调用析构函数。POSIX线程提供pthread_key_create与析构回调机制,确保清理逻辑正确执行。

2.2 pthread_cleanup_push与异常安全的关系

在多线程编程中,线程可能因取消请求而提前终止,此时如何保证资源的正确释放成为关键问题。`pthread_cleanup_push` 提供了一种机制,用于注册线程清理处理函数,确保在异常退出时仍能执行必要的清理操作。
清理函数的注册与执行
通过 `pthread_cleanup_push` 注册的函数遵循栈式后进先出(LIFO)顺序执行,适用于释放互斥锁、关闭文件描述符等场景。

void cleanup_handler(void *arg) {
    pthread_mutex_t *lock = (pthread_mutex_t *)arg;
    pthread_mutex_unlock(lock); // 确保锁被释放
}

void* thread_func(void *arg) {
    pthread_cleanup_push(cleanup_handler, &mutex);
    pthread_mutex_lock(&mutex);
    
    // 模拟工作或可能被取消的阻塞操作
    do_some_work();
    
    pthread_cleanup_pop(0); // 0表示不执行,1则执行清理函数
    return NULL;
}
上述代码中,若线程在持有锁时被取消,`cleanup_handler` 会自动调用,避免死锁。参数 `arg` 传递了需释放的互斥锁地址,确保上下文正确性。该机制增强了程序的异常安全性,使资源管理更具确定性。

2.3 基于setjmp/longjmp的清理触发原理

在C语言中,`setjmp`和`longjmp`提供了一种非局部跳转机制,常用于异常处理或资源清理场景。当调用`setjmp`时,当前执行环境被保存;随后任意深度的函数调用中调用`longjmp`,可使程序流回退至`setjmp`点,从而触发中间栈帧的销毁。
工作流程解析
  • setjmp(jb)首次返回0,标记跳转起点;
  • longjmp(jb, val)恢复该环境,使setjmp二次返回val(非0);
  • 跳转过程中绕过所有函数返回路径,需手动确保资源释放。
#include <setjmp.h>
jmp_buf jb;

void critical_section() {
    longjmp(jb, 1); // 跳出深层调用
}

int main() {
    if (setjmp(jb) == 0) {
        critical_section(); // 正常执行
    } else {
        // 被动进入:清理逻辑在此执行
    }
}
上述机制依赖程序员显式管理资源,在跳转后需重新建立上下文一致性。

2.4 多层嵌套push/pop的行为分析

在栈结构操作中,多层嵌套的 `push` 和 `pop` 行为可能引发数据状态混乱。当多个作用域或线程连续执行嵌套操作时,需严格保证操作顺序与层级匹配。
典型嵌套场景示例

// 伪代码:三层嵌套栈操作
push(A);
  push(B);
    pop();  // 返回 B
  push(C);
    pop();  // 返回 C
pop();      // 返回 A
上述代码展示了嵌套调用中的局部 `pop` 如何影响当前作用域数据。每层 `pop` 仅作用于当前栈顶,不干扰外层逻辑。
操作序列行为对比
步骤操作栈状态
1push(A)[A]
2push(B)[A, B]
3pop()[A]
4pop()[]
正确管理嵌套层级可避免内存泄漏与栈溢出问题。

2.5 实验验证:通过汇编观察清理函数注册过程

在C++对象生命周期管理中,全局或局部静态对象的析构函数(即清理函数)需在程序退出前被正确调用。为观察其注册机制,可通过编译器生成的汇编代码分析`__cxa_atexit`的调用过程。
汇编层面的注册追踪
使用`g++ -S`生成汇编代码,关注`.text.startup`段中对`__cxa_atexit`的调用:

call    __cxa_atexit@PLT
该调用将析构函数指针、对象地址和TLS(线程局部存储)模块索引作为参数注册到退出处理链表中,确保`std::atexit`语义的正确执行。
参数与执行逻辑分析
  • 第一个参数:析构函数地址
  • 第二个参数:待清理对象的内存地址
  • 第三个参数:所属动态库的TLS模块描述符
系统维护一个退出函数栈,程序正常终止时逆序调用,保障依赖顺序安全。

第三章:载体线程资源管理的典型场景

3.1 动态内存与锁资源的自动释放实践

在现代系统编程中,动态内存与锁资源的管理直接影响程序的稳定性与性能。手动释放资源容易引发泄漏或死锁,因此采用自动化机制尤为关键。
RAII 与智能指针的应用
C++ 中的 RAII(Resource Acquisition Is Initialization)理念通过对象生命周期管理资源。例如,使用 std::unique_ptr 自动释放堆内存:

std::unique_ptr<int> data = std::make_unique<int>(42);
// 离开作用域时,内存自动释放
该指针在构造时获取资源,析构时自动调用删除器,无需显式调用 delete。
锁的自动管理
类似地,std::lock_guard 可确保互斥量在作用域结束时释放:

std::mutex mtx;
{
    std::lock_guard<std::mutex> lock(mtx);
    // 临界区操作
} // 自动解锁
即使临界区发生异常,析构函数仍会被调用,有效避免死锁。

3.2 文件描述符与信号量的异常安全关闭

在多线程与异步编程中,资源泄漏是常见隐患。文件描述符和信号量若未在异常路径中正确释放,将导致资源耗尽或死锁。
资源生命周期管理
关键在于确保无论函数正常返回还是提前退出,资源都能被释放。RAII(资源获取即初始化)是常用模式。

func processFile(filename string) error {
    file, err := os.Open(filename)
    if err != nil {
        return err
    }
    defer file.Close() // 异常安全的关键

    sem := acquireSemaphore()
    defer sem.Release()

    // 业务逻辑
    return doWork(file)
}
上述代码中,defer 确保 Close 和 Release 在函数退出时执行,无论是否发生错误。
常见陷阱与规避策略
  • 遗漏 defer 调用,尤其在多重嵌套中
  • 在 goroutine 中使用 defer,可能无法及时释放
  • 信号量未配对 Acquire/Release 导致死锁

3.3 结合线程取消状态实现优雅退出

在多线程编程中,强制终止线程可能导致资源泄漏或状态不一致。通过设置线程取消状态,可实现安全的优雅退出机制。
线程取消状态控制
POSIX 线程提供 `pthread_setcancelstate` 和 `pthread_setcanceltype` 接口,用于动态控制线程的可取消性:

#include <pthread.h>

void cleanup_handler(void *arg) {
    printf("清理资源: %s\n", (char*)arg);
}

void* worker_thread(void* arg) {
    pthread_cleanup_push(cleanup_handler, "文件句柄");
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

    while (1) {
        // 工作逻辑
        pthread_testcancel(); // 显式插入取消点
    }

    pthread_cleanup_pop(0);
    return NULL;
}
上述代码中,`PTHREAD_CANCEL_DEFERRED` 确保取消请求仅在取消点(如 `pthread_testcancel()`)生效,避免中途打断。通过 `pthread_cleanup_push` 注册的清理函数,保障了资源释放的可靠性。
取消状态组合策略
  • 禁用取消:临时保护关键区段
  • 延迟取消:推荐模式,确保在安全点响应
  • 异步取消:高风险,仅用于特定场景

第四章:安全释放资源的编程模式与陷阱规避

4.1 正确配对push与pop避免资源泄漏

在使用栈结构管理资源时,必须确保每次 `push` 操作都有对应的 `pop` 操作,否则会导致资源堆积和内存泄漏。
常见错误场景
  • 异常路径未执行 `pop`
  • 多出口函数遗漏资源释放
  • 循环中 `push` 但未及时 `pop`
代码示例与分析

void process_request() {
    push_resource(ctx);
    if (error_occurred()) {
        return; // 错误:缺少 pop
    }
    pop_resource(); // 仅在正常路径执行
}
上述代码在发生错误时直接返回,未调用 `pop_resource()`,导致资源未释放。应使用 RAII 或 `goto cleanup` 模式统一释放。
推荐实践
使用成对操作的封装机制,确保所有执行路径都能正确匹配 `push` 与 `pop`,防止资源泄漏。

4.2 避免在清理函数中调用非异步安全函数

在信号处理或程序终止时,清理函数(如通过 `atexit` 注册的函数)常用于释放资源。然而,若在其中调用非异步安全函数,可能导致未定义行为。
异步安全函数的定义
异步安全函数是指可在信号上下文中安全调用的函数,它们不会引入竞态条件。POSIX 标准仅列出有限的异步安全函数,如 `write`、`signal` 等。
常见非异步安全函数示例
  • printf —— 内部使用静态缓冲区
  • malloc/free —— 涉及堆管理,非可重入
  • pthread_mutex_lock —— 可能导致死锁

void cleanup_handler() {
    write(STDERR_FILENO, "Exiting...\n", 11); // 安全
    // printf("Exiting...\n"); // 危险:非异步安全
}
上述代码使用 write 而非 printf,避免在信号处理路径中引入不可重入函数调用,确保清理逻辑的安全性。

4.3 使用RAII思想封装C语言中的自动清理

在C++中,RAII(Resource Acquisition Is Initialization)是一种核心资源管理机制,尽管C语言本身不支持构造/析构函数,但可通过技巧模拟其实现。
利用局部对象与atexit实现自动释放
通过将资源绑定到结构体,并注册atexit清理函数,可在程序退出时自动释放资源。

#include <stdlib.h>
#include <stdio.h>

typedef struct {
    FILE* file;
} AutoFile;

void cleanup(AutoFile* af) {
    if (af->file) {
        fclose(af->file);
        printf("文件已自动关闭\n");
    }
}
上述代码定义了一个包含文件指针的结构体,并提供清理函数,在后续结合atexit或作用域控制实现自动化。
结合C++ RAII特性封装C资源
更自然的方式是在C++中封装C风格资源:

class ScopedFILE {
    FILE* fp;
public:
    explicit ScopedFILE(const char* path) { fp = fopen(path, "w"); }
    ~ScopedFILE() { if (fp) fclose(fp); }
    FILE* get() const { return fp; }
};
构造时获取资源,析构时自动释放,无需手动干预,极大降低资源泄漏风险。

4.4 常见误用案例分析与调试策略

错误的并发控制使用
在高并发场景下,开发者常误用共享变量而未加锁,导致数据竞争。例如以下 Go 代码:

var counter int
for i := 0; i < 100; i++ {
    go func() {
        counter++ // 未同步操作,存在竞态条件
    }()
}
该代码未使用互斥锁(sync.Mutex)保护共享变量 counter,导致结果不可预测。应通过加锁或原子操作(atomic.AddInt)确保线程安全。
调试策略建议
  • 启用竞态检测器:编译时添加 -race 标志以发现数据竞争
  • 使用结构化日志记录协程状态,便于追踪执行流程
  • 通过单元测试模拟高并发边界条件

第五章:从pthread_cleanup到现代线程安全设计的演进思考

资源清理的原始机制
在传统 POSIX 线程编程中,pthread_cleanup_push 和 pthread_cleanup_pop 提供了线程退出前的资源释放机制。例如,当线程持有互斥锁时意外取消,可通过清理例程确保解锁:

void cleanup_handler(void *mutex) {
    pthread_mutex_unlock((pthread_mutex_t *)mutex);
}

void* thread_func(void *arg) {
    pthread_mutex_t *mtx = (pthread_mutex_t *)arg;
    pthread_cleanup_push(cleanup_handler, mtx);
    pthread_mutex_lock(mtx);
    
    // 模拟工作或可能被取消的操作
    sleep(2);
    
    pthread_mutex_unlock(mtx);
    pthread_cleanup_pop(0);
    return NULL;
}
现代并发模型的转变
随着 RAII(资源获取即初始化)在 C++ 中的普及和智能指针的广泛应用,手动管理线程清理已逐渐被更高层抽象替代。Go 语言的 defer 机制进一步简化了资源生命周期控制:
  • 避免裸用 malloc/free,转而使用 std::unique_ptr
  • 用 std::lock_guard 替代手动加锁/解锁
  • 通过 std::async 或 std::jthread(C++20)实现自动 join
工程实践中的演化案例
某高并发日志系统曾因线程取消导致文件句柄泄漏。最初依赖 pthread_cleanup 注册关闭逻辑,后重构为基于 C++17 的 std::shared_ptr 配合自定义删除器:

auto file_handle = std::shared_ptr<FILE>(fopen("log.txt", "w"),
    [](FILE* f) { if(f) fclose(f); });
时代典型技术风险点
早期多线程pthread_cleanup匹配错误、遗漏 pop
现代 C++RAII + 智能指针循环引用、性能开销
射频捷变收发器(RF Agile Transceiver) 国内外产品的现状、发展趋势及对比分析2 由于通信系统的研究、设计和实现的巨大进步,RF(射频)设备的新时代正在到来。特别是,随着通信、航空航天和防务以及高速仪器仪表、物联网(IoT)和协作传感器网络(CSN)的发展,以实现宽带高速通信,移动通信中频谱上不断增加的数据量要求而采用新颖的解决方案,以动态方式满足流量交换。然而,当前最先进的技术和设备需要一个合理的成熟时间来满足当前和即将到来的通信标准。 阅读详情

相关推荐

树莓派通过TTL3.3转485 Modbus采集水表

所需道具 树莓派0,我用的是树莓派zero wh; 具有光电直读功能的有线水表,我用的是咸鱼淘的埃美柯LXSY-20E1; TTL3.3 转 485模块,带隔离的贵些; 5V转12V升压模块。 原理 树莓派有UART(GPIO14 Tx 和 GPIO15 Rx)串口通讯功能,电器特性是3.3V TTL,直读远传水表支持M-Bus/485通讯接口,我买的光电直读水表485要求12V供电(根据仪表厂家说明书)。TTL和485虽然都是串口通讯,但电器特性不一样,不能直接接!我已经烧掉一个树莓派...

xhydongda的博客 3443

Linux 线程控制 —— 线程清理 pthread_cleanup_push

Linux 线程控制 —— 线程清理

challenglistic的博客 5084

JPA - @MappedSuperclass - 基类注解

目录前言代码示例 前言 @MappedSuperclass注解一般作为基类的注解,表眀该类是映射的超类,继承于它的子类实体在映射时会自动添加到子类实体的对应数据库表中,用于共同的属性代码复用和模型分离。 代码示例 BaseEntity.java import lombok.Getter; import lombok.Setter; import javax.persistence.MappedSuperclass; import java.util.Date; @Getter @Setter @Ma

Maggieq8324的博客 2066

C++多线程之——pthread_cleanup_push与pthread_cleanup_pop

中,我们模拟了一些线程执行期间的操作,并在函数退出时执行清理函数。清理函数以相反的顺序执行,并打印出相应的清理信息。这些清理工作通常包括释放分配的资源或执行必要的操作,以确保线程退出时不会留下未完成的工作或资源泄漏。、返回从线程函数中等等)时,系统会自动执行清理函数堆栈中的清理函数。清理函数会以相反的顺序执行,即最后一个压入堆栈的函数会最先执行。这表示在线程退出时,将按照相反的顺序执行清理函数。类型的参数,用于传递给清理函数,以便它在执行时能够访问到需要清理的资源或数据。在这个示例中,我们使用。

ALL BE WELL的博客 937

AstrBot插件开发全攻略:从零编写一个天气查询插件(Python实战)

本文提供了一份详细的AstrBot插件开发实战指南,手把手教你使用Python从零编写一个智能天气查询插件。内容涵盖插件系统核心设计、开发环境搭建、API调用与数据处理、自然语言交互实现以及插件打包发布全流程,帮助你快速掌握基于AstrBot框架的聊天机器人功能扩展技能。

weixin_29212867的博客 1087

用AI从0开始量化交易-制定学习计划安装学习环境

量化小白,利用AI从零开始学量化

weixin_52285994的博客 2113

pthread_cleanup_push/pop

void pthread_cleanup_push(void (*routine)(void*), void *arg); void pthread_cleanup_pop(int execute);//这里的int参数,0是不执行push的内容,非0是执行。 原型很简单,功能跟atexit()差不多,只不过一个是线程一个是进程。 用来设置在push/pop内线程退出时要做的事情。

nosmatch的专栏 3422

线程清理(pthread_cleanup_push函数和pthread_cleanup_pop函数)

看了一会儿,没看懂这个,绝了。书上写的颠三倒四。文档给每个函数两句话。也是没看懂啊!

zy010101博客 2301

【Go语言实战】(3) Gin + Gorm 简单备忘录 | 含接口文档

Go语言实战:TodoList 备忘录

面向生活编程 6140

基于计算机视觉的无人便利店技术:从算法到部署的系统化实战指南

摘要:本文系统介绍了基于计算机视觉的无人便利店技术方案,提出"商品检测-跟踪-动作识别-防损-结算"五段式流水线架构。详细阐述了YOLOv8-Seg商品检测、OC-Sort多目标跟踪、3D-CNN+ST-GCN动作识别等核心算法实现,并完成NVIDIA Jetson Xavier NX边缘端的优化部署。通过TensorRT量化、DeepStream加速等技术手段,系统在保持94.7%动作识别准确率的同时,将漏单率降至0.8%,单店云端算力成本较行业平均降低84%。所有代码已开源,可直接应

博客 626

pthread_cleanup_push()

线程终止时的清理 不论是可预见的线程终止还是异常终止,都会存在资源释放的问题,在不考虑因运行出错而退出的前提下,如何保证线程终止时能顺利的释放掉自己所占用的资源,特别是锁资源,就是一个必须考虑解决的问题。 最经常出现的情形是资源独占锁的使用:线程为了访问临界资源而为其加上锁,但在访问过程中被外界取消,如果线程处于响应取消状态,且采用异步方式响应,或者在打开独占锁以前的运行路径上存在取消

木易云清 1116

基于Simulink进行步进电机的重复控制仿真建模

目的:通过引入一个周期延迟环节来补偿系统的周期性误差,从而提高系统对周期性参考信号或扰动的跟踪性能。方法内部模型原理:在控制器中嵌入一个与周期性信号相关的模型(例如周期延迟环节),以实现对周期性误差的零稳态误差控制。滤波器设计:为了避免高频噪声放大,通常会在重复控制器中加入低通滤波器。优势对周期性信号具有良好的跟踪性能。不需要精确的数学模型即可实现高性能控制。挑战:需要合理设计重复控制器的参数以避免系统不稳定。

MHD0815的博客 382

从新手到专家:掌握载体线程资源释放的7个核心步骤(附代码实例)

掌握载体线程的资源释放关键步骤,避免内存泄漏与性能损耗。本文详解适用场景、RAII机制、智能指针管理等核心方法,提升系统稳定性。从新手到专家的进阶指南,值得收藏

BreakVein的博客 646

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Go / C / Python / Java 四语言对照学习总览

按统一维度横向对比四门语言的核心知识点,便于交叉记忆与迁移学习。

2401_83227843的博客 955

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

linux高级编程之线程间的通信(pthread_cleanup_push和pthread_cleanup_pop)

linux高级编程之线程间的通信(pthread_cleanup_push和pthread_cleanup_pop)          线程可以安排他退出时需要调用的函数,这与进程可以用atexit函数安排进程退出时需要调用的函数是类似的。这样的函数称为线程清理处理程序,线程可以建立多个清理处理程序。处理程序记录在栈中,也就是说他们的执行顺序与他们注册的顺序相反。       pthread...

那时风起 2万+

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

pthread_cleanup_push与pthread_cleanup_pop的理解

一、为什么会有pthread_cleanup_push与pthread_cleanup_pop: 一般来说,Posix的线程终止有两种情况:正常终止和非正常终止。线程主动调用pthread_exit()或者从线程函数中return都将使线程正常退出,这是可预见的退出方式;非正常终止是线程在其他线程的干预下,或者由于自身运行出错(比如访问非法地址)而退出,这种退出方式是不可预见的。 不论是可预见的线程终止还是异常终止,都会存在资源释放的问题,在不考虑因运行出错而退出的前提下,如何保证线程终止时能顺利的释放

木牛的博客 1338

linux下pthread_cleanup_push和pthread_cleanup_pop

pthread_cleanup_push的使用 该函数为当前的线程注册一个清理回调函数,清理函数在使用push的时候压入线程的一个栈中。 那么该清理函数何时会被调用呢? 记住,pthread_cleanup_push必须和pthread_cleanup_pop同时使用。 当push后,在线程退出前使用pop,便会调用清理函数。 pthread_cleanup_pop有一个参数,如果在最后调用pop...

weixin_40021744的博客 1372

多线程基础(Linux)

YoYuanZhizheng的博客 415

Posix线程编程指南(4)-线程终止

杨沙洲2001 年 11 月这是一个关于Posix线程编程的专栏。作者在阐明概念的基础上,将向您详细讲述Posix线程库API。本文是第四篇将向您讲述线程中止。1.线程终止方式一般来说,Posix的线程终止有两种情况:正常终止和非正常终止。线程主动调用pthread_exit()或者从线程函数中return都将使线程正常退出,这是可预见的退出方式;非正常终止是线程在其他线程的干预下,或者由

1753

linux线程退出清理函数(详解)

和进程退出函数一样,线程也可以注册它退出时要调用的函数,这样的函数称为线程清理处理程序。处理程序在栈中,故它们的执行顺序与它们注册时的顺序相反。线程可以建议多个清理处理程序。3.用非零execute调用。2.响应其它线程的取消请求。调用注册的清理处理函数。

2403_83472896的博客 767

线程的资源回收:pthread_detach与pthread_cleanup_push/pthread_cleanup_pop的组合

线程退出时需要回收资源,一方面回收线程本身的资源,另一方面还需要回收线程使用的特殊资源,例如互斥锁(回收互斥锁,也就是解锁),malloc开辟的空间。pthread_join 阻塞函数 pthread_tryjoin_np 非阻塞函数。单个线程可以通过3种方式退出,因此可以在不终止整个进程的情况下,停止它的控制流。2)线程可以被同一进程中的其他线程用pthread_cancel所取消。1)线程可以简单地执行完后结束,返回值是线程的退出码。3)线程调用pthread_exit。

symsyq的博客 1208

linux中pthread_join()与pthread_detach()详解

前言: 1.linux线程执行和windows不同,pthread有两种状态joinable状态和unjoinable状态,如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)。只有当你调用了pthread_join之后这些资源才会被释放。若是unjoinable状态的线程,这些资源在线程函数退出时或pthread...

魏波 10万+

pthread_create、pthread_cleanup_push、pthread_cleanup_push、pthread_cancel及signal使用示例

pthread_create、pthread_cleanup_push、pthread_cleanup_push、pthread_cancel及signal使用示例

小小白的日常分享 309

pthread_cleanup_push和pthread_cleanup_pop详解

线程清理处理程序:        void pthread_cleanup_push(void (*routine)(void*),void *arg);          //通过这个函数注册线程处理函数,即将routine放入栈中;arg为routine的参数;          void pthread_cleanup_pop(int execute);      //该函数的作用是...

江清月明 949

linux pthread_cleanup_push 线程实现,关于 pthread_cleanup_push 的问题

关于 pthread_cleanup_push 有如下描述:================================从pthread_cleanup_push()的调用点到pthread_cleanup_pop()之间的程序段中的终止动作(包括调用pthread_exit()和取消点终止)都将执行pthread_cleanup_push()所指定的清理函数。================...

weixin_35858450的博客 373
上一篇: 【JFR性能诊断新高度】:一键生成专业级分析报告的秘诀
下一篇: 【稀缺资料】百万级物联网终端状态同步架构设计(首次公开内部实现细节)
DevPath
博客等级 码龄1年 179粉丝 2176原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值