我希望调用一个异步函数(任务完成后我会提供回调函数)。
我希望在单个线程中完成这个操作。
我希望调用一个异步函数(任务完成后我会提供回调函数)。
我希望在单个线程中完成这个操作。
使用现代C++或旧版C++和一些boost库可以实现可移植性。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++方法(使用需要这个#define的gcc 4.5.2)
#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++11开始,纯C++确实有线程的概念,但异步调用函数最简洁的方法是使用C++11 async命令以及future。这最终看起来很像您在pthread中执行相同操作的方式,但它可以在所有操作系统和平台上100%移植。
假设您的函数具有返回值... 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循环很容易 - 只需创建一个future数组即可。
QueueUserAPC
- 当你使用SleepEx
或WaitForSingleObjectEx
时,回调将被执行。std::async
和std::future
... 现代编译器肯定支持它们。虽然我确实无法理解它们,所以一个两行代码不到5个编译错误...所以 QueueUserAPC 得加一分。 - Damon这需要完成两个步骤。
首先,将函数调用打包以便稍后执行。
其次,安排执行时间。
安排执行时间取决于实现的其他方面。如果你知道“何时完成此任务”,那么你所需要的就是返回并检索“函数调用”,然后调用它。因此,我不确定这是否真的是一个大问题。
第一部分实际上是关于函数对象,甚至函数指针。后者是传统的C回调机制。
对于一个函数对象,你可能会有:
class Callback
{
public:
virtual void callMe() = 0;
};
list<>
: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);
doSomeWorkWithCallback(myCallback)
会立即返回,同时与调用者并行执行工作,并在稍后完成工作时调用 myCallback
。可惜... - kqnr正如其他人所说,你在普通的C++中技术上是做不到的。
然而,你可以创建一个管理器来接受你的任务并进行时间分片或时间调度;每次函数调用时,管理器使用计时器来测量进程所需的时间量;如果进程所需的时间少于预定时间,并且它认为可以在不超过剩余时间的情况下完成另一个调用,则可以再次调用它;如果函数确实超过了分配的时间,那么下一次更新时该函数将有更少的时间运行。因此,这将涉及创建一个相当复杂的系统来为您处理它。
或者,如果你有一个特定的平台,你可以使用线程或创建另一个进程来处理工作。