簡體   English   中英

C++ 線程等效於 pthread_exit

[英]C++ thread equivalent of pthread_exit

我需要一個等效於pthread_exit的 C++ 來制作一個 function ,當調用它時會導致調用線程退出。

在 C 中,使用pthreads.h我簡單地調用了pthread_exit 我是 C++ 的新手,需要使用它的<thread> ,我找不到類似的 function。

我正在使用 C++17,代碼必須在 Linux 上編譯(可能在 MacOs 上)。

沒有直接的方法可以做到這一點 - 終止線程的正常方法是從線程啟動時調用的頂級 function 返回 - 但您可以通過在您希望的點拋出異常來實現相同的效果終止線程並在線程的頂級 function 中捕獲它。 這樣做的好處是線程的堆棧被正確展開並且任何相關的析構函數都被調用。

例如:

#include <iostream>
#include <thread>
#include <exception>

class thread_exit_exception : public std::exception {};

void thread_subfunc ()
{
    std::cout << "Entering thread_subfunc\n";
    thread_exit_exception e;
    throw e;
    std::cout << "Leaving thread_subfunc (never executed)\n";
}

void thread_func ()
{
    std::cout << "Entering thread_func\n";
    try
    {
        thread_subfunc ();
    }
    catch (const thread_exit_exception&)
    {
    }
    std::cout << "Leaving thread_func\n";
}

int main()
{
    std::cout << "Entering main\n";
    std::thread t = std::thread (thread_func);
    t.join ();
    std::cout << "Leaving main\n";
}

Output:

Entering main
Entering thread_func
Entering thread_subfunc
Leaving thread_func
Leaving main

現場演示

C++ 比 C 更依賴其調用堆棧。 C++ 程序經常使用 RAII,這意味着資源綁定到經常存在於堆棧上的對象。 此類對象的用戶期望這些對象被正確銷毀。 If a function creates a stack object, it expects that at some point in the future, control will return to that function and the stack object will be destroyed.

因此,沒有機制讓具有一定堆棧深度的線程簡單地離開 go。 std::thread僅在到達傳遞給thread構造函數的 function 的末尾時結束(從線程 function 調用std::terminate發出的異常)。

鑒於此,最好重新構建您的代碼,以便您永遠不需要導致線程 function 從調用圖中的某個任意位置退出。 使您希望當前線程退出的唯一點是線程的主 function 內的位置。

例如,線程池的典型工作方式是每個線程的主 function 進入睡眠狀態,等待某種形式的任務被該線程丟棄。 當任務可用時,它會執行該任務。 任務完成后,它會檢查是否有新任務,如果沒有可用的,它會重新進入睡眠狀態,直到任務准備好。

在這樣的線程池中,沒有線程會停止 單個任務停止,但實際的std::thread是永恆的(或者至少與池一樣長)。

如果一個任務需要終止,那么這種終止本質上就代表了該任務的執行失敗。 在 C++ 中,拼寫為“拋出異常”。 主線程會將所有任務調用放在一個try塊中,並帶有一個用於特定異常類型的catch塊。 然后它可以向任何人報告任務失敗,然后 go 檢查新任務。

這可以確保清理任務的調用堆棧。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM