C++ 异步 IO 可以使用操作系统提供的底层 API 来实现,例如在 Windows 中可以使用 I/O Completion Port,而在 Linux 中可以使用 epoll 或者 kqueue 等。在 C++11 以后的版本中,也提供了 std::async 和 std::future 等标准库来支持异步 IO 操作。
下面是一个简单的使用例程:
#include <iostream>
#include <string>
#include <future>
// 异步读取文件
std::future<std::string> readFileAsync(const std::string& filename)
{
return std::async(std::launch::async, [filename] {
std::ifstream file(filename);
std::string content((std::istreambuf_iterator<char>(file)), (std::istreambuf_iterator<char>()));
return content;
});
}
int main()
{
std::future<std::string> futureContent = readFileAsync("test.txt");
// 这里可以做其他的事情
// 获取异步操作的结果
std::string content = futureContent.get();
std::cout << content << std::endl;
return 0;
}
这个例程中,readFileAsync 函数会返回一个 std::future 对象,表示异步读取文件的结果。在主函数中,可以继续做其他的事情,而不需要等待文件读取完成。当需要获取文件读取结果时,可以通过 futureContent.get() 来获取。注意,如果异步操作还没有完成,get() 函数会阻塞当前线程,直到异步操作完成并返回结果。
阻塞线程可以使用超时功能,
可以使用超时功能来避免永久阻塞线程。在 C++11 中,std::future 对象提供了一个 wait_for 函数,可以指定一个超时时间来等待异步操作完成。如果超时时间到了,wait_for 函数会返回一个 std::future_status::timeout 值,表示操作还没有完成。如果操作在超时时间内完成,wait_for 函数会返回 std::future_status::ready 值,并且可以通过 get 函数来获取结果。
下面是一个示例代码:
#include <iostream>
#include <future>
#include <chrono>
int main()
{
std::future<int> futureInt = std::async(std::launch::async, [] {
std::this_thread::sleep_for(std::chrono::seconds(3));
return 42;
});
// 等待异步操作完成,但是最多等待 2 秒钟
std::future_status status = futureInt.wait_for(std::chrono::seconds(2));
if (status == std::future_status::ready) {
std::cout << "Result: " << futureInt.get() << std::endl;
} else if (status == std::future_status::timeout) {
std::cout << "Timeout occurred!" << std::endl;
} else {
std::cout << "Unexpected error occurred!" << std::endl;
}
return 0;
}
在这个示例代码中,异步操作会等待 3 秒钟才返回结果。在主线程中,我们使用 wait_for 函数等待 2 秒钟来获取异步操作的结果。如果异步操作在 2 秒钟内完成,我们就可以通过 get 函数获取结果并输出。如果等待超时,就会输出 "Timeout occurred!"。