有的时候需要在service(记做s1)的method内访问其他service(记做s2)的method,如果s2的method需要较长的时间才能返回,那么通过普通的同步调用,会阻塞住s1,导致s1在此期间无法处理其他请求。那么可否在s1内用普通的异步的方式调用s2的method呢?由于普通的method是通过return返回调用结果的,当通过异步方式调用时,在s1的method的return时,是还没拿到返回值的(因为返回值是在异步调用的回调中获取的),所以也无法return。
这种情况可以使用协程的方式完成。
//sleep_service.cpp
#include
#include
#include
#include
#include
#include
#include using namespace std;string doSleep()
{cout<<"doSleep begin"<(io);conn->request_name("sleep.service");auto server = sdbusplus::asio::object_server(conn);shared_ptr iface = server.add_interface("/sleep_obj","sleep_infterface.data");iface->register_method("Sleep", doSleep);iface->initialize();io.run();return 0;
}
定义proxy service
//proxy_service.cpp
#include
#include
#include
#include
#include
#include
#include using namespace std;string doCallSleep(boost::asio::yield_context yield, shared_ptr conn)
{cout<<"1 proxy dosleep begin"<yield_method_call(yield, ec, "sleep.service", "/sleep_obj","sleep_infterface.data", "Sleep");if (ec){cout << "call Sleep failed: ec = " << ec << '\n';return "Sleep failed";}cout<<"1 proxy dosleep end"<yield_method_call(yield, ec, "sleep.service", "/sleep_obj","sleep_infterface.data", "Sleep");if (ec){cout << "call Sleep failed: ec = " << ec << '\n';return "Sleep failed";}cout<<"2 Sleep res="< conn, int d1, int d2)
{boost::system::error_code ec;int resAdd = conn->yield_method_call(yield, ec, "calculate.service", "/calculate_obj","calculate_infterface.data", "AddInt", d1, d2);if (ec){cout << "call addAddIntint failed: ec = " << ec << '\n';return -1;}cout<<"AddInt res="<(io);conn->request_name("proxy.service");auto server = sdbusplus::asio::object_server(conn);shared_ptr iface = server.add_interface("/proxy_obj","proxy_infterface.data");iface->register_method("CallSleep", [conn](boost::asio::yield_context yield) {return doCallSleep(yield, conn);});iface->register_method("CallAddInt", [conn](boost::asio::yield_context yield, int d1, int d2) {return doCallAddInt(yield, conn, d1, d2);});iface->initialize();io.run();return 0;
}
将sleep_service, calculate.service, proxy.service都加载起来,然后通过busctl进行测试:
在shell1里运行:
busctl call proxy.service /proxy_obj proxy_infterface.data CallSleep --user
在shell2里运行:
busctl call proxy.service /proxy_obj proxy_infterface.data CallAddInt ii 1 2 --user
可以看到proxy_service的输出:
1 proxy dosleep begin
AddInt res=3
1 proxy dosleep end
1 Sleep res=Sleep done
2 proxy dosleep begin
2 Sleep res=Sleep done
2proxy dosleep end
可以看出proxy_service可以同时响应多个请求,而不会把自己阻塞。
上一篇:EEPROM芯片(24c02)使用详解(I2C通信时序分析、操作源码分析、原理图分析)
下一篇:剧本中的灭世海啸即将到来?特朗普、巴菲特、索罗斯在剧本之内? 剧本中的灭世海啸即将到来?特朗普、巴菲特、索罗斯在剧本之内?