在线程结束时调用 detach()
Calling detach() at the end of the thread
我有一个类似于以下代码的工作线程。在begin_work
中,它会在创建新的工作线程之前检查工作线程是否正在执行。但是,begin_work
永远不会在当前线程退出时创建下一个工作线程,直到我调用 end_work
.
我尝试在线程末尾调用 detach
,它工作正常。在线程末尾调用 detach
是否安全?或者,如何在调用 begin_work
之前不调用 end_work
来安全地创建下一个工作线程?
class thread_worker {
private:
std::thread worker;
// ... other menbers
public:
thread_worker() {};
~thread_worker() { end_work(); };
void begin_work() {
if (!worker.joinable()) {
worker = std::thread { &thread_worker::do_work, this };
}
}
void do_work() {
// ... access other members ...
if (exit not by notify) {
worker.detach(); // can I call detach?
}
}
void end_work() {
if (worker.joinable()) {
// notify worker to exit
worker.join();
}
}
};
编辑:
我的目的是无阻塞地调用 begin_work
。如果有一个正在执行的工作线程,那么该函数将 return 直接或 return 一个 is_working
错误。否则,无缝地创建一个新的工作线程。
因为 std::thread::joinable()
总是 returns true
直到 join
或 detach
被调用。因此,即使当前工作线程已经退出,以后对 begin_work
的调用也永远不会创建新的工作线程。
因此,我需要一种在线程结束时自动分离的机制。
I have tried to call detach at the end of the thread and it works fine
在访问 worker
时存在 数据竞争 - 这是未定义的行为。当 begin_work
测试 worker.joinable()
时,do_work
可能会同时分离它(对 worker.detach()
的调用)。
您可以改为在创建时立即分离:
worker = std::thread { &thread_worker::do_work, this };
worker.detach();
但是,这可以同时留下多个线程 运行,这与您一次 运行 一个工作线程的要求相矛盾(但为什么只有一个?这只会让线程变得毫无意义) .
相反,您可以这样做:
void begin_work() {
end_work();
worker = std::thread { &thread_worker::do_work, this };
}
确保上一个线程完成。
根据您的编辑,您只需要检查是否可以 加入 无需等待 - 这似乎是您想要分离的原因。您可以改为使用原子标志来做到这一点。基本上,您只需处理上面提到的 数据竞争。
class thread_worker {
private:
std::thread worker;
std::atomic_bool w_done {true};
// ... other menbers
public:
thread_worker() {};
~thread_worker() { end_work(); };
void begin_work() {
if (w_done) {
end_work();
worker = std::thread { &thread_worker::do_work, this };
}
}
void do_work() {
// ... access other members ...
w_done = true;
}
void end_work() {
w_done = false;
if (worker.joinable()) {
// notify worker to exit
worker.join();
}
}
};
我有一个类似于以下代码的工作线程。在begin_work
中,它会在创建新的工作线程之前检查工作线程是否正在执行。但是,begin_work
永远不会在当前线程退出时创建下一个工作线程,直到我调用 end_work
.
我尝试在线程末尾调用 detach
,它工作正常。在线程末尾调用 detach
是否安全?或者,如何在调用 begin_work
之前不调用 end_work
来安全地创建下一个工作线程?
class thread_worker {
private:
std::thread worker;
// ... other menbers
public:
thread_worker() {};
~thread_worker() { end_work(); };
void begin_work() {
if (!worker.joinable()) {
worker = std::thread { &thread_worker::do_work, this };
}
}
void do_work() {
// ... access other members ...
if (exit not by notify) {
worker.detach(); // can I call detach?
}
}
void end_work() {
if (worker.joinable()) {
// notify worker to exit
worker.join();
}
}
};
编辑:
我的目的是无阻塞地调用 begin_work
。如果有一个正在执行的工作线程,那么该函数将 return 直接或 return 一个 is_working
错误。否则,无缝地创建一个新的工作线程。
因为 std::thread::joinable()
总是 returns true
直到 join
或 detach
被调用。因此,即使当前工作线程已经退出,以后对 begin_work
的调用也永远不会创建新的工作线程。
因此,我需要一种在线程结束时自动分离的机制。
I have tried to call detach at the end of the thread and it works fine
在访问 worker
时存在 数据竞争 - 这是未定义的行为。当 begin_work
测试 worker.joinable()
时,do_work
可能会同时分离它(对 worker.detach()
的调用)。
您可以改为在创建时立即分离:
worker = std::thread { &thread_worker::do_work, this };
worker.detach();
但是,这可以同时留下多个线程 运行,这与您一次 运行 一个工作线程的要求相矛盾(但为什么只有一个?这只会让线程变得毫无意义) .
相反,您可以这样做:
void begin_work() {
end_work();
worker = std::thread { &thread_worker::do_work, this };
}
确保上一个线程完成。
根据您的编辑,您只需要检查是否可以 加入 无需等待 - 这似乎是您想要分离的原因。您可以改为使用原子标志来做到这一点。基本上,您只需处理上面提到的 数据竞争。
class thread_worker {
private:
std::thread worker;
std::atomic_bool w_done {true};
// ... other menbers
public:
thread_worker() {};
~thread_worker() { end_work(); };
void begin_work() {
if (w_done) {
end_work();
worker = std::thread { &thread_worker::do_work, this };
}
}
void do_work() {
// ... access other members ...
w_done = true;
}
void end_work() {
w_done = false;
if (worker.joinable()) {
// notify worker to exit
worker.join();
}
}
};