[英]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.