如何解决如何在C ++中使函数异步?
| 我想调用一个异步的函数(完成此任务后将提供一个回调)。 我想在单线程中执行此操作。解决方法
这可以用现代C ++甚至是旧的C ++和一些增强功能来移植。 boost和C ++ 11都包含用于从线程获取异步值的复杂工具,但是如果您只需要回调,则只需启动一个线程并调用它即可。
1998 C ++ / boost方法:
#include <iostream>
#include <string>
#include <boost/thread.hpp>
void callback(const std::string& data)
{
std::cout << \"Callback called because: \" << data << \'\\n\';
}
void task(int time)
{
boost::this_thread::sleep(boost::posix_time::seconds(time));
callback(\"async task done\");
}
int main()
{
boost::thread bt(task,1);
std::cout << \"async task launched\\n\";
boost::this_thread::sleep(boost::posix_time::seconds(5));
std::cout << \"main done\\n\";
bt.join();
}
2011 C ++方法(使用gcc 4.5.2,需要使用此#define)
#define _GLIBCXX_USE_NANOSLEEP
#include <iostream>
#include <string>
#include <thread>
void callback(const std::string& data)
{
std::cout << \"Callback called because: \" << data << \'\\n\';
}
void task(int time)
{
std::this_thread::sleep_for(std::chrono::seconds(time));
callback(\"async task done\");
}
int main()
{
std::thread bt(task,1);
std::cout << \"async task launched\\n\";
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << \"main done\\n\";
bt.join();
}
,您不能使用纯C ++。您将需要使用特定于操作系统的机制,并且需要以允许操作系统执行回调的方式暂停执行。例如。对于Windows,QueueUserAPC
-例如,当您SleepEx
或WaitForSingleObjectEx
,长的答案涉及实现自己的任务计划程序,并将“功能”包装到一个或多个任务中。我不确定您是否需要长答案。当然,它不允许您调用某些东西,完全忘掉它,然后在完成某件事时收到通知;但是,如果您有雄心壮志,它将使您可以在某种程度上模拟协程,而不必超出标准C ++的范围。
简短的答案是这是不可能的。使用多个线程或多个进程。如果您透露要开发的操作系统/平台,我可以为您提供更多具体信息。
,有两个步骤可以做到这一点。
首先,打包函数调用,以便以后可以执行。
其次,安排它。
调度取决于实施的其他方面。如果您知道“何时完成此任务”,那么这就是您所需要的-返回并检索“函数调用”并对其进行调用。所以我不确定这一定是一个大问题。
然后,第一部分实际上是关于函数对象甚至函数指针的。后者是C语言的传统回调机制。
对于FO,您可能需要:
class Callback
{
public:
virtual void callMe() = 0;
};
您从中得出并实现认为适合您的特定问题的方法。那么异步事件队列只不过是“ 6”个回调而已:
std::list<Callback*> asyncQ; // Or shared_ptr or whatever.
,我不确定我了解您想要什么,但是如果这是如何利用回调的话:它可以通过定义一个函数指针来工作,如下所示(未经测试):
// Define callback signature.
typedef void (*DoneCallback) (int reason,char *explanation);
// A method that takes a callback as argument.
void doSomeWorkWithCallback(DoneCallback done)
{
...
if (done) {
done(1,\"Finished\");
}
}
//////
// A callback
void myCallback(int reason,char *explanation)
{
printf(\"Callback called with reason %d: %s\",reason,explanation);
}
/////
// Put them together
doSomeWortkWithCallback(myCallback);
,正如其他人所说,从技术上讲,您不能使用纯C ++。
但是,您可以创建一个管理器来承担您的任务,并进行时间分片或时间安排。每次调用函数时,管理器都使用计时器来测量过程花费的时间;如果该过程所花费的时间少于计划的时间,并且认为可以完成另一个呼叫并用完剩余时间而不用结束,则可以再次调用它;如果该功能确实超过了分配的时间,则表示该功能下一次更新运行的时间更少。因此,这将涉及创建一个稍微复杂的系统来为您处理它。
或者,如果您有一个特定的平台,则可以使用线程,或创建另一个进程来处理工作。
,从C ++ 11开始,普通的c ++确实具有线程的概念,但是异步调用函数的最简洁的方法是将C ++ 11异步命令与Future一起使用。最终看起来很像您在pthread中执行相同操作的方式,但是100%可移植到所有OS和平台上:
说你的函数有一个返回值... int = MyFunc(int x,int y)
#include <future>
做就是了:
// This function is called asynchronously
std::future<int> EventualValue = std::async(std::launch::async,MyFunc,x,y);
抓住?您怎么知道什么时候完成的? (障碍)
最终,请执行以下操作:
int MyReturnValue = EventualValue.get(); // block until MyFunc is done
请注意,以这种方式进行并行for循环很容易-只需创建一个期货数组即可。