C++ 如何使函数在C++;?

C++ 如何使函数在C++;?,c++,asynchronous,C++,Asynchronous,我想调用一个异步函数(当这个任务完成时,我会给出一个回调) 我想用单线程来做这个。< /p> 在纯C++中不能。您需要使用特定于操作系统的机制,并且需要一个暂停执行的点,以允许操作系统执行回调。例如,对于Windows,QueueUserAPC-回调将在您执行时执行,例如SleepEx或WaitForSingleObjectEx长长的答案包括实现您自己的任务调度程序,并将“功能”包装到一个或多个任务中。我不确定你是否想要一个长的答案。它当然不允许你打电话给某件事,完全忘记它,然后在事情完成时得到

我想调用一个异步函数(当这个任务完成时,我会给出一个回调)


我想用单线程来做这个。< /p> 在纯C++中不能。您需要使用特定于操作系统的机制,并且需要一个暂停执行的点,以允许操作系统执行回调。例如,对于Windows,
QueueUserAPC
-回调将在您执行时执行,例如
SleepEx
WaitForSingleObjectEx

长长的答案包括实现您自己的任务调度程序,并将“功能”包装到一个或多个任务中。我不确定你是否想要一个长的答案。它当然不允许你打电话给某件事,完全忘记它,然后在事情完成时得到通知;但是,如果你感觉有抱负,它将允许你模拟某个级别的协同程序而不超出标准C++。
简而言之,这是不可能的。使用多线程或多进程。如果您泄露了您开发的操作系统/平台,我可以给您提供更具体的信息。

我不确定我是否理解您想要什么,但如果是如何使用回调:它通过定义函数指针来工作,如下所示(未经测试):


正如其他人所说,在技术上,C++不能。p> 但是,您可以创建一个管理器,负责执行任务并进行时间切片或时间安排;对于每个函数调用,管理器使用计时器来测量该过程所用的时间;如果进程花费的时间比计划的少,并且它认为它可以完成另一个调用并在不重复的情况下用完剩余的时间,那么它可以再次调用它;如果函数确实超过了分配的时间,则表示函数下次运行更新的时间更短。因此,这将涉及到创建一个稍微复杂的系统来为您处理它


或者,如果您有一个特定的平台,您可以使用线程,或者创建另一个进程来处理该工作

执行此操作有两个方面

首先,打包函数调用以便以后可以执行

第二,安排时间

调度取决于实施的其他方面。如果您知道“此任务何时完成”,那么您只需要返回并检索“函数调用”并调用它。所以我不确定这是否一定是个大问题

第一部分是关于函数对象,甚至函数指针。后者是来自C的传统回调机制

对于FO,您可能有:

class Callback
{
public:
  virtual void callMe() = 0;
};
您可以从中派生,并根据您认为适合您的具体问题来实现它。异步事件队列不过是回调的
列表

std::list<Callback*> asyncQ; // Or shared_ptr or whatever.
std::list asyncQ;//或者共享的ptr或者其他什么。

> > P>这是可以用现代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();
}
#包括
#包括
#包括
无效回调(常量std::字符串和数据)
{
STD:CUT< P> C++ 11,普通C++有一个线程的概念,但是最简单的方法是异步调用函数,使用C++ 11异步命令和未来。这看起来很像在PthOrths中做同样的事情,但是它对所有OSES和平台来说是100%便携的:

假设函数有一个返回值…int=MyFunc(intx,inty)


注意,这样做并行for循环很容易,只需创建一个未来数组。

C++没有线程的概念。你需要指定你正在使用的操作系统和库,以获得有用的答案。@Naveen:我还没有找到一个不支持pthreads的C/C++系统。如果它满足异步要求,这将是非常棒的-也就是说g
doSomeWorkWithCallback(myCallback)
将立即返回,同时继续与调用者并行执行工作,
myCallback
将在稍后某个时间在所述工作完成时被调用。唉……是的,这正是我想要的使用runloop可以在单个线程中执行异步操作(但你可能需要一个完整的框架来支持这一点)。苹果的Objective-C/Cocoa框架就是一个很好的例子,说明了如何做到这一点。好吧,我不会把Cocoa称为任何事情的“好”例子(IMHO!;),但是是的-这是单线程任务调度器的一个很好的例子。我正在使用Bada,但我不确定是否每个人都熟悉它。这就是为什么我要问一个通用的方法。从理论上讲,如果你能弄清楚
std::async
std::future
…现代编译器肯定支持这些。尽管我确实不能弄清楚我想知道这是否可以用定时器来实现。我知道这在symbian中是可能的。我使用的是Bada框架。他们有一个定时器库。但我不确定如何准确地做到这一点。我不知道我的函数需要多少时间,这就是为什么我需要它成为async@yogesh:在这种情况下,您应该在单独的线程中执行此操作。如果您使用的是单个线程,并且具有阻塞时间较长(>0.1s)的函数您将在UI中看到它,因为它不会立即响应和/或动画变得不稳定。@yogesh:正如DarkDust所说,您真的在追求线程化。也许您应该深入并尝试一下。如果您的工作任务可以分解为一系列较小的任务(即<0.1s)对于单独排队的任务,您可以使用如上所述的队列,并在GUI空闲时间内对其进行处理。在2020年,这是最佳答案,但这会启动新线程,对吗?
#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();
}
#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();
}
#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