C++ 在不阻塞/等待主操作的情况下启动新线程
也许对我的问题有一个非常简单的解决方案,但我真的对周围所有的刺激感到困惑 我的问题是: 我想启动一个由回调系统引发的任务(计算、文件系统操作等),回调系统调用C++ 在不阻塞/等待主操作的情况下启动新线程,c++,multithreading,boost,C++,Multithreading,Boost,也许对我的问题有一个非常简单的解决方案,但我真的对周围所有的刺激感到困惑 我的问题是: 我想启动一个由回调系统引发的任务(计算、文件系统操作等),回调系统调用CallbackReceived函数,我想将此操作传递给一个线程,通常由对象的成员函数表示。线程不能保证完成,因此它应该在一段时间后取消它 比如(不知道这是否100%正确): 基本上,tThread.join()等待线程的返回。在等待时,我的main无法接收任何可能传入的回调,因为它被阻塞并且处于休眠状态 那么,我们能做些什么,在执行操作时
CallbackReceived
函数,我想将此操作传递给一个线程,通常由对象的成员函数表示。线程不能保证完成,因此它应该在一段时间后取消它
比如(不知道这是否100%正确):
基本上,tThread.join()等待线程的返回。在等待时,我的main无法接收任何可能传入的回调,因为它被阻塞并且处于休眠状态
那么,我们能做些什么,在执行操作时运行线程而不阻止调用初始程序?您可以在需要计算结果时调用
join
。
类似于“未来”模式。无论如何,您必须使线程变量成为callbackreceived
函数的全局变量(您可以编写一些包装器)。
注意:当线程完成其“工作”时,您可以调用join-任何内容都不会被阻止。您想对计算结果做什么? 您的主线程在.join()中被阻止 如果要处理其他回调,则必须返回正常的执行流,等待另一个调用 然后你必须问自己,当计算完成后,你会如何处理计算结果。也许线程可以将结果放在共享资源的某个地方,然后优雅地完成
您必须首先理清代码应该做什么(处理回调、启动线程、对结果做什么),然后才能考虑实现它。boost和C++11中有一些新的结构,称为promise和future,可能适合您,但首先您必须考虑您想要什么。实际上,您可以在主线程睡眠时调用回调。它只会在线程的上下文(堆栈)上运行 您可能不想在此时调用join,但可能要晚一点或永远不要 示例(伪代码):
您的代码似乎与实际不同,因为tThread不是指针,您可以像tThread.join()一样使用它。另外,如果不想等待线程完成,请不要调用join。也许未来对你来说是更好的工具?@Plasmah谢谢你的提示,我错过了。你说得对。结果将被存储在某个地方,在这种情况下并不重要。也许只有打印件。但你记得我,这根线永远不会完成,我忘了记住。因此,它应该在一段时间后取消。我稍微改变了一下话题,很抱歉给您带来不便。谢谢您的示例。为什么
join()
如此重要?但是除此之外,Worker
和Main
由不同的.h类文件定义。但正如我们所知,它们不能相互包含。你有什么提示吗?
// ...
MyObject object;
// ...
void CallbackReceived(int parameter) {
boost::thread tThread(&MyObject::calculate, *&object);
boost::asio::deadline_timer tDeadlineTimer(_ioService, boost::posix_time::seconds(2));
tDeadlineTimer.async_wait(boost::bind(DeadlineTimeOut, boost::asio::placeholders::error));
tThread.join();
}
class Worker {
void doWork(void * mainthread){
Main* main = static_cast<Main*>(mainthread);
while(hasWorkTodo){
//work
//inform main
main->callbackwithinformation(information);
}
}
class Main{
atomi_int filesfound;
void main_part(){
//start worker
boost::thread thread(&Worker::doWork, &object, this);
while(hasworktodo){
//do work
//use filesfound here
}
//About to finish make sure we join our thread
thread.join();
}
void callbackwithinformation(int updatedcount){
//here we set a flag or pass some object
//probably will need an atomic operation
filesfound = updatedcount;
}
}
//worker.h
class mainthread;
class Worker {
void doWork(void * mainthread);
}
//worker.cpp
#include "main.h"
void Worker::doWork(/* and so on*/}
//main.h
class Main{
atomi_int filesfound;
void main_part();
void callbackwithinformation(int updatedcount);
}
//main.cpp
//no need for worker.h here
void Main::main_part() /* implementation and so on */