我有一个类似于下面代码的工作线程。在begin_work中,在创建新的工作线程之前,它将检查工作线程是否正在执行。但是,在调用begin_work之前,当当前线程退出时,end_work将永远不会创建下一个工作线程。
我试着在线程的末尾调用detach,它可以正常工作。在线程末尾调用detach安全吗?或者,在调用end_work之前,如何安全地创建下一个工作线程而不调用begin_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。如果执行中有一个工作线程,则函数将直接返回或返回is_working错误。否则,创建一个新的工作线程无缝。
因为std::thread::joinable()总是返回true,直到调用join或detach为止。因此,即使当前工作线程已经退出,begin_work的未来调用也永远不会创建新的工作线程。
因此,我需要一个机制来自动分离在线程的末尾。
发布于 2020-07-17 11:47:48
我尝试在线程结束时调用detach,它运行良好。
在访问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 };
} 这确保了前面的线程完成。
基于yuor编辑,您只需要检查是否可以不用等待就可以加入--这似乎是您想要分离的原因。你可以用一个原子标志来做这件事。基本上,您只需要处理上面提到的数据竞赛。
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();
}
}
};https://stackoverflow.com/questions/62952941
复制相似问题