mar*_*964 6 c++ multithreading c++11 stdthread
我想设置一个函数(或lambda函数)的调用,以便在当前线程退出时自动发生,但std::thread除非我接管线程创建的整个任务或手动确保,否则我看不到任何可行的方法.每个线程调用一些我总是提供的特定函数作为它的最后一个操作.
基本上,我想要的功能,其原型可能类似于这样的东西:
on_thread_exit(const std::function<void()> &func);
Run Code Online (Sandbox Code Playgroud)
当调用on_thread_exit的线程最终终止时,将执行必要的设置以确保自动调用给定函数,并且不需要在创建线程或终止时显式调用任何特定函数.
Dav*_*e S 20
你可以使用thread_local存储来完成它,因为C++ 11应该在线程退出后调用析构函数.你必须确保你有一个正确支持它的编译器.
#include <stack>
#include <function>
void on_thread_exit(std::function<void()> func)
{
class ThreadExiter
{
std::stack<std::function<void()>> exit_funcs;
public:
ThreadExiter() = default;
ThreadExiter(ThreadExiter const&) = delete;
void operator=(ThreadExiter const&) = delete;
~ThreadExiter()
{
while(!exit_funcs.empty())
{
exit_funcs.top()();
exit_funcs.pop();
}
}
void add(std::function<void()> func)
{
exit_funcs.push(std::move(func));
}
};
thread_local ThreadExiter exiter;
exiter.add(std::move(func));
}
Run Code Online (Sandbox Code Playgroud)
基本上,此函数创建thread_local上述类的对象.这基本上是静态的,除了在线程退出时被销毁.当被调用时,它将函数推送到向量上,当它被破坏时,它会运行函数.
您可以通过on_thread_exit()从任何线程调用来使用它,该线程将创建退出对象,该对象将按照与放入线程队列相反的顺序运行您的函数(可以根据需要随意修改).
这是基于Dave S解决方案的简化/缩短版本,该解决方案使用具有以下属性的更多C++ 11功能:
ThreadExiter只使用一次,我们可以组合变量声明,避免public/ private(classto struct)并删除复制构造函数/赋值运算符std::stack为基于范围的for循环和std::dequeadd()方法请注意,这std::deque只会在调用所有函数之后才会破坏回调函数,这可能是也可能不是你想要的 - 如果你需要在函数对象被调用之后(以及在调用任何其他函数对象之前)将其销毁),使用像Dave的解决方案中的堆栈和弹出元素).
码:
#include <functional>
#include <deque>
void
on_thread_exit(std::function<void()> func)
{
thread_local struct ThreadExiter {
std::deque<std::function<void()>> callbacks;
~ThreadExiter() {
for (auto &callback: callbacks) {
callback();
}
}
} exiter;
exiter.callbacks.emplace_front(std::move(func));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4339 次 |
| 最近记录: |