如何在C++中使函数异步?

yog*_*esh 20 c++ asynchronous

我想调用一个异步的函数(我将在完成此任务时给出一个回调).

我想在单线程中执行此操作.

use*_*201 16

从 C++11 开始,普通 C++确实有线程的概念,但异步调用函数的最简洁方法是结合使用 C++11 async 命令和 future。这最终看起来很像在 pthread 中执行相同操作的方式,但它 100% 可移植到所有操作系统和平台:

假设你的函数有一个返回值... int = MyFunc(int x, int y)

#include <future>
Run Code Online (Sandbox Code Playgroud)

做就是了:

// This function is called asynchronously
std::future<int> EventualValue = std::async(std::launch::async, MyFunc, x, y); 
Run Code Online (Sandbox Code Playgroud)

抓住?你怎么知道什么时候完成?(障碍。)

最终,做:

int MyReturnValue = EventualValue.get(); // block until MyFunc is done
Run Code Online (Sandbox Code Playgroud)

请注意,以这种方式执行并行 for 循环很容易 - 只需创建一个 future 数组即可。

  • 2020年,这是最好的答案 (4认同)

Cub*_*bbi 15

这可以使用现代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();
}
Run Code Online (Sandbox Code Playgroud)

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();
}
Run Code Online (Sandbox Code Playgroud)


Eri*_*rik 5

你不能用简单的C++.您需要使用特定于操作系统的机制,并且需要以允许操作系统执行回调的方式暂停执行的点.例如,对于Windows,QueueUserAPC- 回调将在你SleepEx或者你的时候执行WaitForSingleObjectEx