<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>
"); //-->

博客專(zhuān)欄

EEPW首頁(yè) > 博客 > 嵌入式Linux:注冊線(xiàn)程清理處理函數

嵌入式Linux:注冊線(xiàn)程清理處理函數

發(fā)布人:美男子玩編程 時(shí)間:2025-01-21 來(lái)源:工程師 發(fā)布文章

在 Linux 多線(xiàn)程編程中,線(xiàn)程終止時(shí)可以執行特定的清理操作,通過(guò)注冊線(xiàn)程清理函數(thread cleanup handler)來(lái)實(shí)現。

這類(lèi)似于使用 atexit() 注冊進(jìn)程終止處理函數。

線(xiàn)程清理函數用于在線(xiàn)程退出時(shí)執行一些資源釋放或清理工作,例如關(guān)閉文件描述符、釋放內存等。

不同于進(jìn)程,線(xiàn)程可以注冊多個(gè)清理函數,這些清理函數以棧的形式管理,棧是一種先進(jìn)后出的數據結構。

因此,清理函數的執行順序與注冊順序相反。

在 Linux 中,使用 pthread_cleanup_push() 和 pthread_cleanup_pop() 函數分別向線(xiàn)程的清理函數棧添加和移除清理函數。

其原型如下:

void pthread_cleanup_push(void (*routine)(void *);
void *arg);void pthread_cleanup_pop(int execute);


參數說(shuō)明:

  • pthread_cleanup_push()用于將清理函數推入棧中。

    • routine: 指向清理函數的函數指針,清理函數沒(méi)有返回值,并接受一個(gè) void * 類(lèi)型的參數。

    • arg: 傳遞給清理函數的參數,當清理函數執行時(shí),該參數作為 routine() 的輸入。

  • pthread_cleanup_pop()用于從清理函數棧中彈出最近添加的清理函數。

    • execute: 指定是否執行清理函數。如果為 0,則只移除清理函數而不執行它;如果為非 0,則不僅移除還會(huì )執行清理函數。

線(xiàn)程清理函數執行的場(chǎng)景:

  • 當線(xiàn)程調用 pthread_exit()退出時(shí),清理函數會(huì )自動(dòng)執行。

  • 當線(xiàn)程響應取消請求時(shí)(如通過(guò) pthread_cancel()取消線(xiàn)程),清理函數會(huì )被執行。

  • 當通過(guò)非 0 參數調用 pthread_cleanup_pop() 時(shí),棧頂的清理函數會(huì )被執行。

以下代碼展示了如何使用 pthread_cleanup_push() 和 pthread_cleanup_pop() 注冊和移除清理函數:


void cleanup(void *arg) {
    printf("Cleaning up: %s\n", (char *)arg);
}
void *thread_function(void *arg) {
    pthread_cleanup_push(cleanup, "Resource 1");
    pthread_cleanup_push(cleanup, "Resource 2");
    // 模擬線(xiàn)程工作
    printf("Thread is running...\n");
    // 調用pthread_exit()會(huì )觸發(fā)清理函數的執行
    pthread_exit(NULL);
    // 清理函數必須成對使用,因此即使退出后也要調用pthread_cleanup_pop
    pthread_cleanup_pop(1);
    pthread_cleanup_pop(1);
}
int main() {
    pthread_t thread;
    // 創(chuàng  )建一個(gè)線(xiàn)程
    if (pthread_create(&thread, NULL, thread_function, NULL) != 0) {
        perror("Failed to create thread");
        return 1;
    }
    // 等待線(xiàn)程結束
    pthread_join(thread, NULL);
    return 0;
}


解釋說(shuō)明:

  • 線(xiàn)程中注冊了兩個(gè)清理函數,分別為 "Resource 1" 和 "Resource 2"。

  • 當線(xiàn)程調用 pthread_exit() 時(shí),棧中的清理函數按后進(jìn)先出的順序執行,因此會(huì )先打印 "Cleaning up: Resource 2",再打印 "Cleaning up: Resource 1"。

注意事項:

  • pthread_cleanup_push() 和 pthread_cleanup_pop() 并不是普通函數,而是宏實(shí)現的,必須在相同的作用域內成對出現,不能在代碼中分開(kāi)使用。

  • 清理函數只會(huì )在線(xiàn)程通過(guò) pthread_exit() 或響應取消請求時(shí)執行。

    如果線(xiàn)程通過(guò) return 語(yǔ)句退出,清理函數不會(huì )被執行。

通過(guò)使用 pthread_cleanup_push() 和 pthread_cleanup_pop(),可以確保在線(xiàn)程終止時(shí)執行所需的清理操作,這在資源管理和異常處理中非常有用。

清理函數的自動(dòng)執行使得多線(xiàn)程編程中的資源釋放更加簡(jiǎn)潔、安全。

*博客內容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀(guān)點(diǎn),如有侵權請聯(lián)系工作人員刪除。



關(guān)鍵詞: 嵌入式 Linux

相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>