std::使用类成员函数创建线程 - 最佳实践
std::thread creation with class member function - best practice
假设我们有一些类SomeAlgorithm
,它已经用一堆数据和其他变量初始化了。我们现在想使用它的成员函数execute
开始计算。让我们创建一个std::thread
并使用主线程join
它。
#include <thread>
#include <memory>
class SomeAlgorithm {
public:
void execute();
private:
// variables, eg. std::vector<int> data
};
int main() {
// (1)
{
SomeAlgorithm a1;
std::thread t1(&SomeAlgorithm::execute, &a1);
t1.join();
}
// (2)
{
SomeAlgorithm* a2 = new SomeAlgorithm();
std::thread t2(&SomeAlgorithm::execute, a2);
t2.join();
delete a2;
}
// (3)
{
std::unique_ptr<SomeAlgorithm> a3(new SomeAlgorithm());
std::thread t3(&SomeAlgorithm::execute, a3.get());
t3.join();
}
}
创建此类线程的首选方法是什么?是否有任何最佳实践? 在内存使用方面,确保释放分配的内存的最节省方法是什么?
切勿使用 (2(。这与线程无关。切勿使用显式new
。智能指针(如果您需要拥有指针(。
至于(3(在你的例子中,你不需要指针。如果线程超出对象的作用域,则需要,例如:
std::thread t3;
{
auto a3 = std::make_unique<SomeAlgorithm>();
t3 = std::thread{&SomeAlgorithm::execute, std::move(a3)};
}
t3.join();
您的代码也存在一些问题。使用make_unique
.有一些微妙的错误可以在没有它的情况下蔓延。正如我所说,永远不要使用明确的新。但最重要的是,不要使用get()
因为它会使智能指针的整个点无效。
至于(1(我个人更喜欢:
// (1)
{
SomeAlgorithm a1;
std::thread t1{[&]{ a1.execute(); }};
t1.join();
}
通常(至少对我来说(它是(1(的形式:
{
SomeAlgorithm a1;
std::thread t1([&a1]() { a1.execute(); });
t1.join();
}
(3( 仅在您确实想从主线程中断开对象时使用。例如(从 C++14 开始(:
{
auto a3 = std::make_unique<SomeAlgorithm>();
std::thread t3([a{move(a3)}] { a->execute(); });
t3.join();
}
它可能会更清楚地显示您的意图(如果您不关心主线程中的实际结果(,但它的效率较低,主要是因为跨线程堆分配/释放。
(2( 只是一种已弃用(自 C++11 起(的执行方式 (3(。
相关文章:
- 将线程中的数据存储到全局容器的最佳方法?
- 最佳做法是从另一个线程访问 qml 中的Q_PROPERTY
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- std::使用类成员函数创建线程 - 最佳实践
- 等待线程的最佳方式是什么
- 存储/传递 v8 承诺解析器供以后使用的最佳实践?(结合C++线程)
- 套接字发送(.)线程的最佳数量
- 线程数据封装最佳实践
- 最佳多线程全局变量管理
- 从QTcpSocket上的数据流中连续运行复杂算法的最佳Qt线程解决方案是什么
- 多线程 UI 的最佳方式
- 暂停和恢复线程的最佳解决方案是什么?
- 使用来自不同线程的实时数据更新QTableView的最佳策略
- 从线程更新进度条的最佳方式
- C++/Win32 我在 Windows 2000+ 上启动线程的最佳方式
- 控制对多线程程序中字符串对象的访问的最佳方法
- std::线程管理:用法和最佳实践
- 在多个相互依赖的线程上进行封送处理和等待的算法、模式或最佳实践
- Eclipse CDT 多线程调试不是最佳的 - 如何以独占方式运行线程
- 使用Qt框架减少多线程应用程序中数据库连接的最佳策略