英文:
self destructive std:thread
问题
我将有一个能生成自毁线程的函数。问题是在创建的线程结束之前,我不能重用该函数。另一方面,我希望新创建的线程能在函数作用域外继续运行,并在线程完成时被销毁。
我的代码如下。
#include <iostream>
#include <thread>
#include <chrono>
struct ThreadGaurd
{
public:
ThreadGaurd(void (*Func) (int) , int number);
~ThreadGaurd();
private:
public:
std::thread m_Thread;
private:
};
void CreateThread()
{
static int Counter = 0;
ThreadGaurd m_Thread([](int counter)
{
std::chrono::duration<double, std::milli> m_Duration(500);
while (true) {
std::this_thread::sleep_for(m_Duration);
std::cout << "My " << counter << "'th Thread is Running";
}
}, Counter);
return;
}
int main(int argc, char *argv[])
{
CreateThread();
CreateThread();
return 0;
}
ThreadGaurd::ThreadGaurd(void (*Func)(int), int number) : m_Thread(Func,number)
{
}
ThreadGaurd::~ThreadGaurd()
{
if (m_Thread.joinable())
m_Thread.join();
}
英文:
I'm going to have a function capable of generating auto-destructive threads. The problem is that I'm not allowed to reuse the function until the created thread has finished. On the other hand, I want the spawned thread to continue running outside the scope of the function and be destroyed whenever the thread is done.
My code is as follows.
#include <iostream>
#include <thread>
#include <chrono>
struct ThreadGaurd
{
public:
ThreadGaurd(void (*Func) (int) , int number);
~ThreadGaurd();
private:
public:
std::thread m_Thread;
private:
};
void CreateThread()
{
static int Counter = 0;
ThreadGaurd m_Thread([](int counter)
{
std::chrono::duration<double, std::milli> m_Duration(500);
while (true) {
std::this_thread::sleep_for(m_Duration);
std::cout << "My " << counter << "'th Thread is Running";
}
}, Counter);
return;
}
int main(int argc, char *argv[])
{
CreateThread();
CreateThread();
return 0;
}
ThreadGaurd::ThreadGaurd(void (*Func)(int), int number) : m_Thread(Func,number)
{
}
ThreadGaurd::~ThreadGaurd()
{
if (m_Thread.joinable())
m_Thread.join();
}
答案1
得分: 4
你想要在线程上调用 std::thread::detach
。在 detach
返回之后,可以安全地销毁 std::thread
对象,因为线程不再与该对象关联,将继续独立运行。
以下代码演示了使用 detach
。
#include <iostream>
#include <thread>
#include <chrono>
using std::cout, std::endl;
using namespace std::chrono_literals;
template<class F>
void create_detached_thread(F&& func) {
std::thread th{std::forward<F>(func)};
th.detach();
}
int main(int argc, const char *argv[]) {
cout << "Main started" << endl;
create_detached_thread([]() {
cout << "First thread starting" << endl;
std::this_thread::sleep_for(400ms);
cout << "First thread done" << endl;
});
create_detached_thread([]() {
cout << "Second thread starting" << endl;
std::this_thread::sleep_for(200ms);
cout << "Second thread done" << endl;
});
cout << "Main sleeping" << endl;
std::this_thread::sleep_for(1s);
cout << "Main done" << endl;
return 0;
}
输出:
Main started
Main sleeping
Second thread starting
First thread starting
Second thread done
First thread done
Main done
如在这个 答案 中所解释的,必须在销毁 std::thread
对象之前调用 join
或 detach
,否则将调用 std::terminate
。
如果需要使用 detach
,可能需要提供同步机制,以确保主线程在所有已分离的线程完成之前不会结束。
英文:
You want to call std::thread::detach
on the thread. After detach
returns, it is safe to destroy the std::thread
object as the thread is no longer associated with the object and will continue running independently.
The following code demonstrates using detach
.
Sample Code
#include <iostream>
#include <thread>
#include <chrono>
using std::cout, std::endl;
using namespace std::chrono_literals;
template<class F>
void create_detached_thread(F&& func) {
std::thread th{std::forward<F>(func)};
th.detach();
}
int main(int argc, const char *argv[]) {
cout << "Main started" << endl;
create_detached_thread([]() {
cout << "First thread starting" << endl;
std::this_thread::sleep_for(400ms);
cout << "First thread done" << endl;
});
create_detached_thread([]() {
cout << "Second thread starting" << endl;
std::this_thread::sleep_for(200ms);
cout << "Second thread done" << endl;
});
cout << "Main sleeping" << endl;
std::this_thread::sleep_for(1s);
cout << "Main done" << endl;
return 0;
}
Output
Main started
Main sleeping
Second thread starting
First thread starting
Second thread done
First thread done
Main done
As explained in this answer, you have to call either join
or detach
on a thread before the std::thread
object is destroyed, otherwise std::terminate
is called.
If you need to use detach
, you will probably want to provide a synchronization mechanism so that the main thread will not end unless all of the detach
'ed threads have finished.
Update
The following code is the same as above except it uses a std::atomic<int>
to wait for the two detached threads to finish before allowing main
to finish.
#include <atomic>
#include <iostream>
#include <thread>
#include <chrono>
using std::cout, std::endl;
using namespace std::chrono_literals;
template<class F>
void create_detached_thread(F&& func) {
std::thread th{std::forward<F>(func)};
th.detach();
}
int main(int argc, const char *argv[]) {
cout << "Main started" << endl;
std::atomic<int> ndone{};
create_detached_thread([&]() {
cout << "First thread starting" << endl;
std::this_thread::sleep_for(400ms);
cout << "First thread done" << endl;
++ndone;
ndone.notify_one();
});
create_detached_thread([&]() {
cout << "Second thread starting" << endl;
std::this_thread::sleep_for(200ms);
cout << "Second thread done" << endl;
++ndone;
ndone.notify_one();
});
cout << "Main sleeping" << endl;
ndone.wait(0);
ndone.wait(1);
cout << "Main done" << endl;
return 0;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论