簡體   English   中英

std :: thread什么時候執行線程?

[英]std::thread when is thread executed?

我已經瀏覽了一些線程教程,但我很好奇一件事。

std::thread Child([](){ std::cout << "When am I executed?" << std::endl << std::endl; });

//Some other code

Child.join();

//I'm guessing now my thread would be running

線程是在我調用join()時執行還是在創建線程和調用join之間的某個時間運行? 如果在調用join()時執行它,只是為了檢查我的理解,它告訴要執行的部分,你的程序繼續在主線程上,最終子線程在主線程使用的同一內存上做了一些工作?

如果我想為泛型類創建一個包裝器,我會想做類似下面的事情,但我似乎無法完全弄明白。 我對在內存方面管理線程很困惑。

class Sync {
private:
    int val;

public:
    Sync() : val(0) {}
    void Inc() {val++}
    int Value() { return val; }
};

class Async {
private:
    Sync Foo;
    std::mutex mtx;
    std::vector<std::thread*> Children;
public:
    //I would need a new thread each time I called Inc
    void Inc() { 
        Children.push_back(new std::thread([&]() {
            mtx.lock();
            Foo.Inc();
            mtx.unlock();
        }));


    }
    //But how do I know when it is safe to delete Child?  
    int Value() { 
        for(auto& thds : Children) {
            thds->join();
            delete thds; 
        }
        Children.clear();
        return Foo.Value(); }
};

我正在考慮一個合適的位置可能在線程函數的末尾,因為不再需要Child但是如果你試圖從內部破壞線程會發生什么? 我猜這聽起來不是一個壞主意。 我怎么知道什么時候可以刪除我的線程? 有更好的方法嗎?

修改上面的代碼以反映下面的建議。

我現在意識到教程正在討論關於拋出異常的內容,所以我應該使用互斥鎖而不是mtx.lock()我想。

的目的join是,本質上,等待線程完成。 所以一旦Child->join(); 返回,你的線程已經完成。 當然,您也可以在析構函數中執行Child->join() [或者在某些其他方面,確保在某些時候調用它]。

請注意,線程將在實際創建的時間和連接結束之間的某個時刻開始運行。 無法確定何時會發生這種情況。 如果系統上已經運行了很多線程,則時間將在所有線程之間分配,並且您的線程可能無法運行幾秒鍾。 另一方面,如果有一個CPU坐在那里“弄亂它的手指”,它很可能在主線程超出new std::thread(...)構造之前啟動[因為std::thread won' t返回,直到線程被正確創建,並且一些數據存儲在線程對象中,因此在到達Child->join()時線程可能已經完成。 如果不知道系統處於什么狀態,就無法確定這些選項中的哪一個。

操作系統很重要,但它相當普遍。 線程被安排執行。 當操作系統到處實際運行時,完全無法預測。 你可以在擁有多個內核的機器上“快速”獲得不錯的賠率,這在今天是普遍可用的。

thread :: join()只是確保線程完成執行。 永遠不會真正編寫這樣的代碼,啟動一個線程然后等待它完成是完全沒有意義的。 也可以直接執行線程的代碼。 通過創建線程而不會影響操作系統的結果相同。

您無法知道您的線程將以何種順序或核心運行。

一個posix線程基本上被linux視為一個與另一個共享其堆的進程。 內核將安排它們並決定使用哪個核心。 例如,查看生成的(受保護的)程序集,您將看不到任何“多核/多線程編程”,因為這是在內核級別完成的。

這就是為什么存在諸如連接之類的函數和諸如互斥鎖/信號量之類的工件的原因。 照顧比賽條件和其他相關的東西。

線程是在我調用join()時執行還是在創建線程和調用join之間的某個時間運行?

在創建線程后執行(啟動)線程,具體取決於可能需要一些時間的可用資源。 join()方法等待(阻塞),直到線程完成其工作。

一個建議:我不會將變量命名為Sync對象This ,令人困惑,因為存在this關鍵字。

您可以在Async::Inc()調用join()之后安全地刪除std::thread對象,而且您不需要將引用存儲為成員變量,它只在該函數中使用。

您還可以查看<atomic>標頭, std::atomic<int>std::atomic_int

暫無
暫無

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

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