gflags用法與boost非同步I/O服務經典示例
阿新 • • 發佈:2018-12-16
(第一次從專案中接觸這類知識,還是挺好奇,於是自己寫了一段)
gflags是google的一套開源命令列引數解析工具,在工程化的開發當中經常用到,其安裝可以參考網上,下面僅演示gflags的引數定義、引數檢查、引數傳入。
boost是是一個可移植、提供原始碼的C++庫,作為標準庫的後備,是C++標準化程序的開發引擎之一。c++標準一直都在變,現在c++11用得比較多,但以前的工程裡一直還是習慣使用boost,所以要看懂以前的程式碼,boost還是要看一下的,下面演示了boost非同步服務,通過定時器實現定時輸出功能,並實現了類之間的回撥。
#include <boost/thread.hpp> #include <boost/asio.hpp> #include "gflags/gflags.h" #include <iostream> static int second = 0; boost::shared_mutex myMutex; //定義等待時間 DEFINE_int32(timer_wait_second,2,"wait time in seconds"); class myClass { public: myClass() :myAge(20), myName("alpc40") {} bool setAgeName(const int age, const std::string name) { myAge = age; myName = name; return true; } void outAgeName() { std::cout << myAge << " " << myName <<std::endl; } private: int myAge; std::string myName; }; class cls { //定義回撥形式,與myClass相關 using callBack = std::function<bool(const int, const std::string)>; using printCallBack = std::function<void(void)>; public: cls(); ~cls(); void print(const boost::system::error_code &ec); void RegisteUserCallBack(callBack call_back); void RegistePrintCallBack(printCallBack call_back); private: boost::asio::io_service io_service; boost::asio::deadline_timer timer; boost::thread* thread; callBack my_call_back; printCallBack my_print_call_back; }; //回撥函式 void cls::RegistePrintCallBack(printCallBack call_back) { my_print_call_back = call_back; } //回撥函式 void cls::RegisteUserCallBack(callBack call_back) { my_call_back = call_back; } cls::cls() : timer(io_service, boost::posix_time::seconds(FLAGS_timer_wait_second)) { //timer繫結函式,即當timer結束後,才啟動該函式 timer.async_wait(boost::bind(&cls::print, this, boost::asio::placeholders::error)); thread = new boost::thread([&] { //io_service開始工作,這個時候timer才開始啟動 boost::asio::io_service::work work(io_service); //非同步阻塞,直到work完成才能結束 io_service.run(); }); } cls::~cls() { //釋放時先取消定時器 timer.cancel(); //取消非同步IO服務 io_service.stop(); //取消執行緒 if (thread != nullptr) { //執行緒阻塞,直到thread執行完畢 thread->join(); delete thread; thread = nullptr; } } void cls::print(const boost::system::error_code &ec) { printf("%d s\n", ++second); //使用鎖,寫myClass類 boost::unique_lock<boost::shared_mutex> _(myMutex); my_call_back(second, "haha"); my_print_call_back(); if (second < 8) { //使timer重新激發,繼續執行 timer.expires_from_now(boost::posix_time::seconds(FLAGS_timer_wait_second)); timer.async_wait(boost::bind(&cls::print, this, boost::asio::placeholders::error)); } } //引數賦值檢測函式,使1<FLAGS_timer_wait_second< 60 static bool validateTimer(const char *name, int32_t second) { if (second > 60 || second < 1) return false; return true; } int main(int argc,char **argv) { //註冊引數賦值檢測函式 gflags::RegisterFlagValidator(&FLAGS_timer_wait_second, &validateTimer); //引數來自輸入,自行賦值給FLAGS gflags::ParseCommandLineFlags(&argc, &argv, true); //定義兩個類 myClass heihei; cls haha; //註冊函式,也就是說,在haha類當中可以呼叫heihei類,使heihei類進行改變 haha.RegisteUserCallBack(std::bind(&myClass::setAgeName, &heihei, std::placeholders::_1, std::placeholders::_2)); haha.RegistePrintCallBack(std::bind(&myClass::outAgeName, &heihei)); while (1) { Sleep(1000); //獲得主執行緒ID std::cout << boost::this_thread::get_id() << ":"; //獲得鎖,防止輸出時輸入 boost::unique_lock<boost::shared_mutex> _(myMutex); heihei.outAgeName(); } return 0; }
可以執行下,看看效果與自己的期望是不是一樣,還是挺有意思的