[英]Properly capture (lambda) and safety issues in member function starting a new thread (C++11/14)
我已經瀏覽了各種書籍和在線資源,但仍然不確定如何處理不斷循環的成員函數可能啟動一個新線程的情況,該線程可能需要訪問其他成員函數和變量(有時對其進行突變) )。 以下代碼描述了這種情況:
class Foo {
int read_only;
Object some_big_object;
std::atomic<int> read_and_write;
// more private member variables
void helper_function_a(const Object& value) {
Object copy = value.clone(); // deep copy
std::thread t {[/*what should I put here?*/](){
// read from read_only and WRITE to read_and_write
if (/*some condition which is occasionally true*/)
helper_function_b(copy);
}};
t.detach();
}
void helper_function_b(const Object& value) {
// change value
}
public:
void update() {
// update some_big_object;
// read from read_only and READ OR WRITE from/to read_and_write
helper_function_a(some_big_object);
}
void doSomething;
};
int main() {
Foo f;
while (true) {
f.update();
}
}
我知道我可以將this
放在成員函數中以捕獲所有內容,但是我並不是真的要捕獲所有內容,如果可能的話,僅捕獲我使用的內容,而不要捕獲其他任何內容。 我的真實類更復雜,並且還具有應保持不變但不能聲明const的變量(因為我在構造函數的主體內對其進行了初始化)-確保lambda僅能訪問其使用的內容更加安全。 那我應該放什么呢?
那這個設計呢? 感覺不對-是嗎? 為什么呢? 請注意,在我的真實類(復雜helper_function_a
)中, helper_function_a
失敗-我仍然不確定錯誤的確切位置,但是如果我刪除了lambda並將其helper_function_a
單線程,它將起作用。 在我的應用程序中,我使用helper_function_a在更新動畫時執行大對象的文件IO-感覺寫不起來要從同一線程執行這兩個任務。
最后,以我的方式使用read_and_write是否安全?
如果您在lambda中使用成員函數,則應捕獲this
函數。 你還應該考慮的壽命this
和創建線程helper_function_a
。 我可能建議您在Foo對象中使用某種線程池,並等待/中斷析構函數中的所有線程
如果您不想捕獲this
,則可以嘗試將helper_function_b
(所有在helper_function_b數據中使用的數據)移動到Foo
某個成員並捕獲該成員(不要忘記它的生命周期)
如果您需要長時間初始化的const
成員,則可以使用函數來構建它們:
Foo::Foo(args ...):
member(build_member(args ...)),
...
{};
控制生存期的另一種方法是使用共享指針和std :: enable_shared_from_this,如本示例中所示
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.