linux 文件监控,linux下c++实现文件监控

这是一个C++实现的热切换词典管理类,用于监测词典文件的变化并自动加载新词典。它通过一个后台监控线程定期检查是否有新词典到达,并在确认新词典可用后,在保证线程安全的情况下进行词典的更新。类中包含了读写锁、文件监控、新词典的创建等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#ifndef _HOTSWITCH_DICT_H_

#define _HOTSWITCH_DICT_H_

#include

#include

#include

#include

#include

#include

#include

#include

using std::string;

using std::cerr;

using std::endl;

using std::cout;

namespace hsd {

/** *@brief 获取当前时间 */

inline string _getCurrentTime()

{

time_t t = time(NULL);

/*本地时间:日期,时间 年月日,星期,时分秒*/

struct tm* c_t = localtime(&t);

char buf[20];

sprintf(buf, "%d-%d-%d %d:%d:%d", c_t->tm_year+1900, c_t->tm_mon,

c_t->tm_mday, c_t->tm_hour, c_t->tm_min, c_t->tm_sec);

return string(buf);

}

template class HotSwitchDict;

template

void* monitorThread(void *arg)

{

HotSwitchDict * pHotDict = (HotSwitchDict*)arg;

bool needSleep = false;

uint32_t curSleepTime = 0;

// 检测是否需要停止检测

while( !pHotDict->m_stopMonitor )

{

if( needSleep ) {

if( curSleepTime++ < pHotDict->m_sleepTime ) {

sleep(1);

continue;

}

else {

needSleep = false;

curSleepTime = 0;

}

}

// 检测pHotDict->m_pSwitchDict是否不为空 2012-08-12

// 不为空,判断是否到底备用词典的延迟生命周期

if( pHotDict->m_pSwitchDict != NULL ) {

delete pHotDict->m_pSwitchDict;

pHotDict->m_pSwitchDict = NULL;

}

// 检测新文件是否到来

if(pHotDict->isNewDictArrived())

{

// 构造新的DictType类型指针

pHotDict->m_pSwitchDict =

pHotDict->newDictFunc(pHotDict->getNewDictFileName());

// 判断词典是否加载成功

if(pHotDict->m_pSwitchDict == NULL) {

cerr << "[WARNING] [" << _getCurrentTime() <<

"] Error when load new Dictionary!" << endl;

}

else {

// 加读锁后,交换m_pCurDict和m_pSwitchDict指针

DictType * pDictTemp = pHotDict->m_pCurDict;

pthread_rwlock_wrlock(&pHotDict->m_rwLock);

pHotDict->m_pCurDict = pHotDict->m_pSwitchDict;

// 不在删除,直接将m_pSwitchDict指向原来的内存空间

// 保证指针不删除原来m_pCurDict的指针

pHotDict->m_pSwitchDict = pDictTemp;

pthread_rwlock_unlock(&pHotDict->m_rwLock);

// delete pDictTemp;

// 修改当前内存中的词典名字

pHotDict->switchFileName();

cout << "[INFO] [" << _getCurrentTime()

<< "] New Dictionary Switched!" << endl;

}

needSleep = true;

}

else { // 继续监控

needSleep = true;

}

}

return NULL;

}

// 默认的词典构建对象函数

template

inline DictType * DefaultNewDictFunc(const string & fileName)

{

DictType * tmpDict;

try {

tmpDict = new DictType(fileName.c_str());

}

catch (int e) {

return NULL;

}

return tmpDict;

}

template

class HotSwitchDict

{

public:

typedef DictType* (*NewDictFunc)(const string & fileName);

// 友元函数,需要操作HotSwitchDict的private变量

friend void * monitorThread(void * arg);

/** *@brief HotSwitchDict 构造函数 *@param fileName 词典的文件名 *@param flagFile 词典的监控文件,保存新词典的名字和md5码 *@param sleepTime 每次词典监控的扫描时间间隔 */

HotSwitchDict(const string & fileName, const string & flagFile,

uint32_t sleepTime = 1)

: m_pCurDict(NULL), m_pSwitchDict(NULL), m_fileName(fileName),

m_newFileName(""), m_flagFile(flagFile), m_sleepTime(sleepTime),

m_stopMonitor(false)

{

pthread_rwlock_init(&m_rwLock, NULL);

m_lastUpdateTime = 0;

if( sleepTime < 10 || sleepTime > 3600 ) {

m_sleepTime = 3600;

}

}

/** *@brief 初始化函数,用来初始化词典文件以及监控线程 *@ndf 初始化词典的函数指针 *@return 如果初始化不成功,返回false */

bool init(NewDictFunc ndf)

{

this->setNewDictFunc(ndf);

m_pCurDict = newDictFunc(m_fileName);

if( m_pCurDict == NULL ) {

return false;

}

int err = pthread_create(&m_monitorThread, NULL,

monitorThread, (void*)this);

if( err != 0 ) return false;

return true;

}

/** *@brief 销毁对象,等待监控xiancheng结束,销毁dict指针和读写锁 * todo 屏蔽继承 */

~HotSwitchDict()

{

if( m_pCurDict != NULL )

{

m_stopMonitor = true;

// 取消线程,避免出现sleep时间过长,导致join需要大量时间

//pthread_cancel(m_monitorThread);

// 等待监控线程结束

pthread_join(m_monitorThread, NULL);

// 销毁对象

delete m_pCurDict;

}

m_pCurDict = NULL;

if( m_pSwitchDict != NULL ) {

delete m_pSwitchDict;

m_pSwitchDict = NULL;

}

// 销毁锁

pthread_rwlock_destroy(&m_rwLock);

}

/** *@brief 获取当前dict的指针 */

DictType * getCurDict()

{

return m_pCurDict;

}

/** *@brief 加读锁 */

int32_t rwlock_read_lock()

{

return pthread_rwlock_rdlock(&m_rwLock);

}

/** *@brief 加写锁 */

int32_t rwlock_write_lock()

{

return pthread_rwlock_wrlock(&m_rwLock);

}

/** *@brief 解开锁 */

int32_t rwlock_unlock()

{

return pthread_rwlock_unlock(&m_rwLock);

}

private:

HotSwitchDict() {}

/** *@brief 根据词典文件创建新的dict指针 */

DictType * newDictFunc(const string & fileName)

{

return m_newDictFunc(fileName.c_str());

}

/** *@brief 判断新词典文件是否存在 */

bool isNewDictArrived()

{

// 读取finish文件,得到新词典对应的文件名

if( access(m_flagFile.c_str(), F_OK|R_OK) < 0 )

{

cerr << "[WARNING] [" << _getCurrentTime() << "] flagFile "

<< m_flagFile << " not exist or not readable" << endl;

return false;

}

// 如果文件修改时间比m_lastUpdateTime大,则读取文件

struct stat buf;

if( stat(m_flagFile.c_str(), &buf) < 0 ) {

return false;

}

time_t flagFileTime = buf.st_ctime;

if( flagFileTime <= m_lastUpdateTime )

{

#ifdef DEBUG

cout << "[DEBUG] flagFileTime is smaller than m_lastUpdateTime" << endl;

#endif

return false;

}

std::ifstream in(m_flagFile.c_str());

if( !in.is_open() ) {

cerr << "[ERROR] [" << _getCurrentTime() << "] flagFile "

<< m_flagFile << " opened failed" << endl;

return false;

}

string newfileName;

in >> newfileName;

in.close();

// 判定新文件名是否发生变化

if( newfileName == m_fileName ) {

#ifdef DEBUG

cout << "[DEBUG] newfileName == m_fileName" << endl;

#endif

return false;

}

// 判断新文件是否存在,使用绝对路径

if( access(newfileName.c_str(), F_OK|R_OK) < 0 )

{

cerr << "[WARN] [" << _getCurrentTime() << "] newfileName "

<< newfileName << " not exist or not readable" << endl;

return false;

}

// 保存md5码,并进行验证

m_newFileName = newfileName;

m_lastUpdateTime = flagFileTime;

#ifdef DEBUG

cout << "[DEBUG] [" << _getCurrentTime() <<

"] change m_newFileName to " << m_newFileName << endl;

#endif

return true;

}

string getNewDictFileName()

{

return m_newFileName;

}

/** *@brief 当前词典的文件名修改 */

void switchFileName()

{

m_fileName = m_newFileName;

m_newFileName = "";

}

/** *@brief 设置从一个文件初始化DictType*类型的函数 */

void setNewDictFunc(NewDictFunc ndf)

{

m_newDictFunc = ndf;

}

private:

DictType * m_pCurDict;

DictType * m_pSwitchDict;

string m_fileName;

string m_newFileName;

string m_flagFile;

uint32_t m_sleepTime;

pthread_rwlock_t m_rwLock;

pthread_t m_monitorThread;

bool m_stopMonitor;

NewDictFunc m_newDictFunc;

time_t m_lastUpdateTime;

};

}

#endif // _HOTSWITCH_DICT_H_

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值