gpt4 book ai didi

c++ - 安全 move 在访问其他成员的成员线程中运行 lambda 的对象

转载 作者:行者123 更新时间:2023-11-28 06:27:47 25 4
gpt4 key购买 nike

我有一个类,它有一个 std::thread 成员变量,它运行一个依赖于其他成员变量的 lambda 函数。

举个例子:

struct C {
C() {
thread_ = std::thread([this]() {
running_ = true;
while (running_) {
...
}
});
}
C(C&& rv) {
swap(rv);
}
void swap(C& rhs) {
std::swap(thread_, rhs.thread_); // step 1
std::swap(running_, rhs.running_); // step 2
}
std::thread thread_;
bool running_;
};

int main() {
C c;
C c2 = move(c); // Is c safely moved to c2?
}
  • move 此类物体的安全方法是什么?
  • 捕获[this] move 操作后要指向的对象。
  • 第 1 步之后但第 2 步之前,在 lambda 的 while 循环中访问了哪个对象的 running_

最佳答案

虽然 std::thread肯定是可 move 的,这样做不会神奇地修改任何引用它的指针,或者它的包含对象,如果有的话。

因此,即使你 move 了一个 C ,由包含的 std::thread 管理的线程仍将引用它之前引用的对象。

所以,如果你想安全地 move/交换一个 C , 使用 pimpl-idiom:
只保护指向线程可能访问的资源的指针,并将该指针指向它。
在您的情况下,这意味着:

  1. move running_ :

    struct inner {
    std::atomic<bool> running;
    };
    unique_ptr<inner> data_ = new inner;
  2. 传递指向的数据:

    auto data = &*data_;
    thread_ = std::thread([data]() {
    data->running = true;
    while (data->running) {
    ...
    }
    });

(可选地也 move 线程未访问的数据。)

此外,即使您没有询问,您的 running必须是 std::atomic<bool>所以检查有效。

关于c++ - 安全 move 在访问其他成员的成员线程中运行 lambda 的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28214142/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com