c++类方法线程
c++ class method thread
我有一个类,有一个方法,需要连续运行,但也能够从用户接收输入。所以我想我会让方法运行单独使用一个线程。
代码看起来像这样(只是骨干):
class SystemManager
{
private:
int command;
bool commandAcK;
bool running;
//other vars
public:
SystemManager()
{
//initialisation
}
void runningAlgorithm()
{
while (running)
{
if (commandAcK)
{
//solve command
}
//run algorithm
//print results
}
}
void readCmd()
{
cin >> command;
commandAcK = true;
}
};
int main()
{
SystemManager *SM = new SystemManager;
thread tRunning = SM->runningAlgorithm();
}
现在错误看起来像这样:
没有合适的构造函数将" void
"转换为" std::thread
"
错误C2440 '初始化':无法从'void'转换为'std::thread'
我找到了一个新方法,它不会给我任何错误
std::thread tRunning(&SystemManager::runningAlgorithm, SystemManager());
我不明白的第一件事是,这个方法不使用类的实例,只是泛型函数。如何将其链接到特定实例?我需要它,所以它可以读取变量的值。
其次,"&"
在SystemManager前面做什么?
(&SystemManager::runningAlgorithm)
第三,有没有更好的方法?你有什么主意吗?
提前感谢。
std::thread tRunning(&SystemManager::runningAlgorithm, SystemManager());
确实使用了您的类的实例。它使用的实例是SystemManager()
,这是一个临时的,只对线程可用。如果需要共享实例,则需要自己创建一个实例,并通过引用将其传递给线程,如
SystemManager sys_manager;
std::thread tRunning([&](){sys_manager.runningAlgorithm();});
现在你的调用站点和你的线程有相同的实例。
还需要注意command
和commandAck
需要某种同步保护,因为您可以在读取时对它们进行写操作,从而导致数据竞争和随后的未定义行为。使用std::atmoic
应该适合您。
std::thread
的构造函数接受函子,并可选地接受它的参数。函子是任何可以用operator()
"调用"的对象。
然后它启动一个线程,并在该线程中调用你的函子。
std::thread tRunning(&SystemManager::runningAlgorithm, SystemManager());
这将调用成员函数SystemManager::runningAlgorithm
,传递唯一的参数this
(SystemManager()
创建临时实例)。请记住,成员函数总是接受this
作为第一个参数。
&SystemManager::runningAlgorithm
返回SystemManager
类的成员函数runningAlgorithm
的地址。
在现代c++中,这段代码可以用lambda:
来简化(即使其更具可读性):std::thread tRunning([]{ SystemManager().runningAlgorithm(); });
thread tRunning = SM->runningAlgorithm();
获取运行SM->runningAlgorithm()
(void
)的结果,并尝试以此构建一个线程。但是,如果查看相关的构造函数,就会发现它需要一个类似函数的实参(可能有实参)。
运行它的一种方法是通过lambda函数:
thread tRunning(
[SM](){SM->runningAlgorithm();});
还有两点需要注意:
你应该在它的析构函数被调用之前加入线程,在这种情况下:
tRunning.join();
您有一个(短暂的)内存泄漏。为什么不在堆栈上创建它呢?
SystemManager SM; thread tRunning( [&](){SM.runningAlgorithm();}); tRunning.join();
嗯…我想在使用多线程之前,你需要学习一些c++的基本概念。
然而…在您的代码中,
thread tRunning = SM->runningAlgorithm();
试图把结果的函数(这是void…)在线程类型的变量中…不太可能是对的。
相反,第二段代码接受2个参数:std::thread tRunning(
&SystemManager::runningAlgorithm, //a pointer to a method (a pointer to the code of your function, and that is why you use the "&", even though you could have left that out)
SystemManager()); // An instance of the value, built on the stack.
我猜你会因为缺少"新"这个词而感到困惑(来自更高层次的语言?),但这就是它在这里的工作原理:
SystemManager sm = SystemManager(); // <- variable created on the stack, will be automatically destroyed when out of scope
SystemManager *psm = new SystemManager(); // Created in the heap, while in the stack remains just a pointer to it.
//You will need to delete it when done with :
delete psm;
回答问题
如何将它链接到一个特定的实例?我需要它,所以它可以读取变量的值。
你可以这样做:
int main()
{
SystemManager SM; // = SystemManager(); // <- this is not needed
std::thread tRunning(SystemManager::runningAlgorithm, SM);
// Access SM as you need
// REMEMBER TO CLOSE & JOIN THE THREAD!
tRunning.join();
}
我仍然认为你应该首先习惯基本的概念,否则将很难继续下去。
- 使用 ubuntu 终端在 c++ 上运行线程类的问题
- 在派生自线程类的构造函数中传递字符串
- C++ std::线程调用方法,从对象原因到调用此类的析构函数
- 可中断线程类 C++11 - 遇到错误?
- 将信号从工作线程类连接到控制器类 - QThreads
- Posix 线程类和启动例程 (pthread)
- QTimer 线程的方法 'isActive()' 是安全的吗?
- 停止线程的方法是什么(当我直接从Qthread继承时)
- 线程类无法正常工作
- C++ for 循环中的 11 个线程类成员函数会给出分段错误
- 为什么在从线程执行方法时使用QMetaObject::invokeMethod
- 如何在对话框编辑框中显示来自 UI 线程类 Run() 函数的字符串
- c++11 线程类如何使用类成员函数
- 本机线程类函数的JNI流是什么
- 在C++类中构建互斥保护的线程安全方法
- std::线程类方法错误
- Linux 性能监控,任何监视每个线程的方法
- std::类的线程调用方法
- C++std::线程和方法类
- c++多线程类方法