先解释名字:
你调库就是调用,库调你就是回调;
工作中常见的应用是什么呢?
比如甲,乙合作完成一个功能,甲的functionA里面会调用乙的functionB,那么乙就会将functionB作为回调函数传给甲,乙这个行为就是注册回调函数,甲就可以合适的时间调用functionB
为什么甲不直接调用乙的functionB?
1.甲和乙可以独立地进行开发和维护,比如functionB还没写,怎么调用呢
2.丙,丁同样可以通过注册回调的方式让甲调用
(比如客户端开发时,A点击鼠标触发A响应,B点击鼠标触发B响应,那么组件库会提供一个接口给A,B注册回调,总不能组件库会挨个调用A,B的响应函数吧)
#include <functional>
class Component_A {
public:
using Callback = std::function<void()>;
void registerCallback(Callback callback) {
callback_ = std::move(callback);
}
void unregisterCallback() {
callback_ = nullptr;
}
void functionA() {
std::cout << "Component A is doing something..." << std::endl;
if (callback_) {
callback_();
}
}
private:
Callback callback_;
};
class Component_B {
public:
void functionB() {
std::cout << "Component B is doing its thing." << std::endl;
}
};
int main() {
Component_A componentA;
Component_B componentB;
// 乙将自己的 functionB 作为回调函数,注册给甲
componentA.registerCallback(std::bind(&Component_B::functionB, &componentB));
// 甲会在适当的时候调用乙注册的回调函数
std::cout << "Calling Component A's functionA..." << std::endl;
componentA.functionA();
// 取消注册回调函数
componentA.unregisterCallback();
return 0;
}
贴一个基本的异步和回调的组合应用
使用 std::thread 和回调函数来实现异步读取文件
#include <iostream>
#include <thread>
#include <functional>
#include <fstream>
#include <string>
// 回调函数类型
using FileReadCallback = std::function<void(const std::string&)>;
// 异步读取文件的函数
void readFileAsync(const std::string& filename, FileReadCallback callback) {
std::ifstream file(filename);
if (file.is_open()) {
std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
std::cout << "Start" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(10));
callback(content);
} else {
callback(""); // 传递空字符串表示读取失败
}
}
int main(int argc, char* argv[]) {
std::thread fileReadThread([](const std::string& filename, FileReadCallback callback) {
readFileAsync(filename, callback);
}, "D:\\TEST\\example.txt", [](const std::string& content) {
std::cout << "File content: " << content << std::endl;
});
fileReadThread.detach();
std::cout << "still" << std::endl;
// 继续执行其他任务
// ...
return 0;
}
接下来,我们使用 std::async
替换掉std::thread和回调来启动异步任务。
std::async
的第一个参数 std::launch::async
表示创建一个新线程来执行任务,而不是在当前线程中执行。第二个参数是要执行的函数,第三个及后续参数是函数的参数。
std::async
会自动创建和管理线程,不需要我们手动控制线程的生命周期。并且std::async
返回一个 std::future
对象,可以很方便地获取异步任务的返回值。
#include <iostream>
#include <future>
#include <functional>
#include <fstream>
#include <string>
// 异步读取文件的函数
std::string readFileAsync(const std::string& filename) {
std::ifstream file(filename);
if (file.is_open()) {
std::string content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
std::cout << "Start" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(10));
return content;
} else {
return ""; // 返回空字符串表示读取失败
}
}
int main(int argc, char* argv[]) {
// 启动异步任务读取文件内容
std::future<std::string> fileContentFuture = std::async(std::launch::async, readFileAsync, "D:\\TEST\\example.txt");
std::cout << "still" << std::endl;
// 等待异步任务完成并获取结果
std::string fileContent = fileContentFuture.get();
std::cout << "File content: " << fileContent << std::endl;
return 0;
}