博客專欄

        EEPW首頁 > 博客 > 嵌入式Linux:注冊線程清理處理函數

        嵌入式Linux:注冊線程清理處理函數

        發布人:美男子玩編程 時間:2025-01-21 來源:工程師 發布文章

        在 Linux 多線程編程中,線程終止時可以執行特定的清理操作,通過注冊線程清理函數(thread cleanup handler)來實現。

        這類似于使用 atexit() 注冊進程終止處理函數。

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

        不同于進程,線程可以注冊多個清理函數,這些清理函數以棧的形式管理,棧是一種先進后出的數據結構。

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

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

        其原型如下:

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


        參數說明:

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

          • routine: 指向清理函數的函數指針,清理函數沒有返回值,并接受一個 void * 類型的參數。

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

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

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

        線程清理函數執行的場景:

        • 當線程調用 pthread_exit()退出時,清理函數會自動執行。

        • 當線程響應取消請求時(如通過 pthread_cancel()取消線程),清理函數會被執行。

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

        以下代碼展示了如何使用 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");
            // 模擬線程工作
            printf("Thread is running...\n");
            // 調用pthread_exit()會觸發清理函數的執行
            pthread_exit(NULL);
            // 清理函數必須成對使用,因此即使退出后也要調用pthread_cleanup_pop
            pthread_cleanup_pop(1);
            pthread_cleanup_pop(1);
        }
        int main() {
            pthread_t thread;
            // 創建一個線程
            if (pthread_create(&thread, NULL, thread_function, NULL) != 0) {
                perror("Failed to create thread");
                return 1;
            }
            // 等待線程結束
            pthread_join(thread, NULL);
            return 0;
        }


        解釋說明:

        • 線程中注冊了兩個清理函數,分別為 "Resource 1" 和 "Resource 2"。

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

        注意事項:

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

        • 清理函數只會在線程通過 pthread_exit() 或響應取消請求時執行。

          如果線程通過 return 語句退出,清理函數不會被執行。

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

        清理函數的自動執行使得多線程編程中的資源釋放更加簡潔、安全。

        *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。



        關鍵詞: 嵌入式 Linux

        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 苍梧县| 呼图壁县| 定日县| 张北县| 通化县| 临朐县| 温州市| 吉安市| 新龙县| 德令哈市| 阿荣旗| 郓城县| 蕉岭县| 巴南区| 思南县| 望城县| 铜梁县| 福鼎市| 德州市| 绥中县| 开鲁县| 西乌| 沙雅县| 汤阴县| 崇明县| 竹北市| 普安县| 宜宾市| 霞浦县| 新竹市| 万宁市| 塘沽区| 濮阳县| 易门县| 长治县| 乌海市| 珲春市| 临湘市| 甘谷县| 元谋县| 临沧市|