一、需求來源
最近在項目開發過程中,需要在修改配置後,不重啓程序就可以熱加載配置文件。通過分析可以使用libev的ev_stat實現;
二、Demo代碼
1、關鍵點
ev_stat: 文件觀察者,監控文件屬性的變化
ev_stat_init (ev_stat , callback, const char path, ev_tstamp interval)
ev_stat_start(ev_loop loop,ev_stat)
注意:ev_stat_init中的path需要是絕對路徑;
2、代碼
file_watcher.cpp
#include <iostream>
#include <ev.h>
#include <chrono>
#include <thread>
#include <string>
#include <ctime>
std::string get_current_system_time()
{
auto t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
struct tm* _tm = localtime(&t);
char date[60]{0};
sprintf(date,"%d-%02d-%02d %02d:%02d:%02d",
(int)(_tm->tm_year) + 1900,
(int)(_tm->tm_mon) + 1,
(int)(_tm->tm_mday),
(int)(_tm->tm_hour),
(int)(_tm->tm_min),
(int)(_tm->tm_sec));
return std::string(date);
}
ev_timer timeout_watcher;
ev_stat stat_watcher;
static void timeout_cb(EV_P_ ev_timer* w,int revents)
{
std::string s = "";
s = get_current_system_time();
std::cout<<"["<<s.c_str()<<"] loop..."<<std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
//ev_break(EV_A_ EVBREAK_ONE);
}
static void stat_cb(struct ev_loop *loop, ev_stat* w,int revents)
{
std::cout<<"file change"<<std::endl;
if(w->attr.st_nlink){
std::cout<<"current size "<<(long)w->attr.st_size<<std::endl;
}
}
int main()
{
struct ev_loop* loop = EV_DEFAULT;
ev_timer_init(&timeout_watcher,timeout_cb,3,1);
ev_timer_start(loop,&timeout_watcher);
ev_stat_init(&stat_watcher,stat_cb,"/home/zhuyf/study/cpp/libev/t.log",0.);
ev_stat_start(loop,&stat_watcher);
ev_run(loop,0);
return 0;
}
編譯指令:
g++ file_watcher.cpp -o fw --std=c++11 -lev
運行程序後在另一個窗口更改t.log文件後,運行效果如下
3、總結
需要在項目程序中的回調函數stat_cb內,新增重新加載配置文件的代碼即可;