当我希望线程终止时,是否 ok/safe 删除包含 运行 个线程的 class?
Is it ok/safe to delete a class that contains running threads when I want the threads to terminate?
这是一个简单的例子:
class worker
{
std::thread thread1;
std::thread thread2;
worker(){}
start()
{
thread1 = std::thread([]()
{
std::this_thread::sleep_for(std::chrono::milliseconds(50000));
});
thread1.deteach();
thread2 = std::thread([]()
{
std::this_thread::sleep_for(std::chrono::milliseconds(50000));
});
thread2.deteach();
}
~worker()
{
// Ignore this part! - as per Richard's comment :)
//thread1.join(); // <-- do I need this at all?
//thread2.join(); // <-- do I need this at all?
}
}
int main()
{
worker *p_worker = new worker();
p_worker->start();
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 1 sec
delete p_worker;
}
- 创建工人
- 启动持续 50 秒的线程
- 1秒后删除worker(调用析构函数)
- 在 worker 析构函数中,我重新加入线程(可能应该先检查它们是否可加入?)- 不确定我是否需要这样做。
- 然后worker被销毁
我看过这个问题:how-do-i-terminate-a-thread-in-c11 这表明没有 c11 可移植的方式来终止线程。
问题:
- 线程是否完全销毁(没有 dregs/leaks 剩余)?
- 如果"yes"我需要重新加入线程才能销毁它们吗?
EDIT - Richard pointed out this is N/A
- 这是明智的做法吗?
是的,如果线程仍可连接(运行 且未分离),则线程将被 std::thread
dtor 完全销毁。
That's not good news though, as std::terminate()
will be called, killing the whole process.
一般来说,终止只是为了避免意外状态造成的进一步损害,或者如果应用程序是为在那个确切点无害终止而构建的。
如评论中所述,您不能加入分离的线程。
分离线程意味着 运行 独立。通常,分离 class.
拥有的线程是个坏主意
我建议使用布尔值来控制线程的生命周期。
例如,您可以这样做:
class worker
{
private:
std::thread thread1;
std::atomic<bool> thread1ShouldRun;
std::thread thread2;
std::atomic<bool> thread2ShouldRun;
void workerFunc1() {
bool threadWorkIsDone = false;
while (thread1ShouldRun.load()) {
// Do Stuff
// Set threadXShouldRun to false when you're done
// thread1ShouldRun.store(false);
}
}
void workerFunc2() {
bool threadWorkIsDone = false;
while (thread2ShouldRun.load()) {
// Do Stuff
// Set threadXShouldRun to false when you're done
// thread2ShouldRun.store(false);
}
}
public:
worker() {}
void start()
{
thread1ShouldRun.store(true);
thread1 = std::thread(&worker::workerFunc1, this);
thread2ShouldRun.store(true);
thread2 = std::thread(&worker::workerFunc2, this);
}
~worker()
{
thread1ShouldRun.store(false);
// Protection in case you create a worker that you delete and never call start()
if (thread1.joinable())
thread1.join();
thread2ShouldRun.store(false);
if (thread2.joinable())
thread2.join();
}
};
int main()
{
worker *p_worker = new worker();
p_worker->start();
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 1 sec
delete p_worker; // Threads will be joined here
}
这是一个简单的例子:
class worker
{
std::thread thread1;
std::thread thread2;
worker(){}
start()
{
thread1 = std::thread([]()
{
std::this_thread::sleep_for(std::chrono::milliseconds(50000));
});
thread1.deteach();
thread2 = std::thread([]()
{
std::this_thread::sleep_for(std::chrono::milliseconds(50000));
});
thread2.deteach();
}
~worker()
{
// Ignore this part! - as per Richard's comment :)
//thread1.join(); // <-- do I need this at all?
//thread2.join(); // <-- do I need this at all?
}
}
int main()
{
worker *p_worker = new worker();
p_worker->start();
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 1 sec
delete p_worker;
}
- 创建工人
- 启动持续 50 秒的线程
- 1秒后删除worker(调用析构函数)
- 在 worker 析构函数中,我重新加入线程(可能应该先检查它们是否可加入?)- 不确定我是否需要这样做。
- 然后worker被销毁
我看过这个问题:how-do-i-terminate-a-thread-in-c11 这表明没有 c11 可移植的方式来终止线程。
问题:
- 线程是否完全销毁(没有 dregs/leaks 剩余)?
- 如果"yes"我需要重新加入线程才能销毁它们吗?
EDIT - Richard pointed out this is N/A
- 如果"yes"我需要重新加入线程才能销毁它们吗?
- 这是明智的做法吗?
是的,如果线程仍可连接(运行 且未分离),则线程将被 std::thread
dtor 完全销毁。
That's not good news though, as std::terminate()
will be called, killing the whole process.
一般来说,终止只是为了避免意外状态造成的进一步损害,或者如果应用程序是为在那个确切点无害终止而构建的。
如评论中所述,您不能加入分离的线程。 分离线程意味着 运行 独立。通常,分离 class.
拥有的线程是个坏主意我建议使用布尔值来控制线程的生命周期。
例如,您可以这样做:
class worker
{
private:
std::thread thread1;
std::atomic<bool> thread1ShouldRun;
std::thread thread2;
std::atomic<bool> thread2ShouldRun;
void workerFunc1() {
bool threadWorkIsDone = false;
while (thread1ShouldRun.load()) {
// Do Stuff
// Set threadXShouldRun to false when you're done
// thread1ShouldRun.store(false);
}
}
void workerFunc2() {
bool threadWorkIsDone = false;
while (thread2ShouldRun.load()) {
// Do Stuff
// Set threadXShouldRun to false when you're done
// thread2ShouldRun.store(false);
}
}
public:
worker() {}
void start()
{
thread1ShouldRun.store(true);
thread1 = std::thread(&worker::workerFunc1, this);
thread2ShouldRun.store(true);
thread2 = std::thread(&worker::workerFunc2, this);
}
~worker()
{
thread1ShouldRun.store(false);
// Protection in case you create a worker that you delete and never call start()
if (thread1.joinable())
thread1.join();
thread2ShouldRun.store(false);
if (thread2.joinable())
thread2.join();
}
};
int main()
{
worker *p_worker = new worker();
p_worker->start();
std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // 1 sec
delete p_worker; // Threads will be joined here
}