最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++利用inotify+epoll實(shí)現(xiàn)異步文件監(jiān)控的方法

 更新時(shí)間:2023年08月02日 09:18:26   作者:卻道天涼_好個(gè)秋  
這篇文章講給大家詳細(xì)介紹一下C++利用inotify+epoll實(shí)現(xiàn)異步文件監(jiān)控的方法,inotify是一種異步文件監(jiān)控機(jī)制,文章通過(guò)代碼示例介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下

需求

動(dòng)態(tài)監(jiān)測(cè)linux系統(tǒng)某一個(gè)目錄下文件的變化。具體使用場(chǎng)景如linux下應(yīng)用程序運(yùn)行時(shí)產(chǎn)生日志文件,尤其在程序出現(xiàn)某種異常時(shí),日志文件記錄著錯(cuò)誤出現(xiàn)的原因、時(shí)間及代碼位置等信息,此時(shí)日志文件在增長(zhǎng),但是采用輪詢(xún)的方式定時(shí)查看日志文件尤為消耗性能?;诖藛?wèn)題,采用**“epoll+inotify異步文件監(jiān)控”**的方式可以實(shí)現(xiàn)日志的動(dòng)態(tài)刷新。

inotify

特點(diǎn)

inotify是一種異步文件監(jiān)控機(jī)制,主要包括以下特點(diǎn):

  • 可監(jiān)控目錄或文件訪(fǎng)問(wèn)、讀寫(xiě)、權(quán)限、刪除、移動(dòng)等文件系統(tǒng)事件;
  • 監(jiān)控目錄時(shí),可監(jiān)控目錄下的子目錄或文件,但是不能遞歸監(jiān)控子目錄的目錄或文件;
  • 事件發(fā)生時(shí),由內(nèi)核空間主動(dòng)回調(diào)至用戶(hù)空間,具體為內(nèi)核將事件加入inotify事件隊(duì)列,用戶(hù)可通過(guò)read讀?。?/li>

流程

1)inotify初始化,調(diào)用inotify_init(),返回inotifyFd句柄;

2)創(chuàng)建epoll句柄,調(diào)用epoll_create();

3)注冊(cè)epoll事件,調(diào)用epoll_ctl,將inotifyFd添加至epoll_event結(jié)構(gòu)體;

4)將目錄或文件添加為watch對(duì)應(yīng),調(diào)用inotify_add_watch();

5)啟動(dòng)線(xiàn)程等待epoll事件,調(diào)用epoll_wait();

6)有epoll事件發(fā)生時(shí),調(diào)用read函數(shù)inotify事件;

7)解析inotify_event進(jìn)行事件分析;

接口

epoll

  • 創(chuàng)建epoll句柄
#include <sys/epoll.h>
int epoll_create(int size);
##參數(shù)
- size:監(jiān)聽(tīng)的事件數(shù)目;
  • 注冊(cè)epoll事件
#include <sys/epoll.h>
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
## 參數(shù)
- epfd:epoll_create()返回值;
- op:執(zhí)行的操作。包括EPOLL_CTL_ADD、EPOLL_CTL_MOD、EPOLL_CTL_DEL;
- fd:文件描述符;
- event:結(jié)構(gòu)體epoll_event的指針。
#### 結(jié)構(gòu)體epoll_event
typedef union epoll_data
{
 	void *ptr; /* Pointer to user-defind data */
 	int fd; /* File descriptor */
 	uint32_t u32; /* 32-bit integer */
 	uint64_t u64; /* 64-bit integer */
} epoll_data_t;
struct epoll_event
{
 	uint32_t events; /* epoll events(bit mask) */
 	epoll_data_t data; /* User data */
};
  • 事件等待
#include <sys/epoll.h>
int epoll_wait(int epfd, struct epoll_event *events,
                      int maxevents, int timeout);
## 參數(shù):
- epfd:epoll_create()返回值;
- events:evlist所指向的結(jié)構(gòu)體數(shù)組中返回的是有關(guān)就緒態(tài)文件描述符的信息,數(shù)組evlist的空間由調(diào)用者負(fù)責(zé)申請(qǐng);
- maxevents:指定所evlist數(shù)組里包含的元素個(gè)數(shù);
- timeout:確定epoll_wait()的阻塞行為。<0:一直阻塞,0:執(zhí)行一次非阻塞式地檢查,>0:調(diào)用將阻塞至多timeout毫秒;

inotify

  • 初始化
#include <sys/inotify.h>
int inotify_init(void);
## 返回值
- 返回文件描述符
  • 添加監(jiān)控對(duì)象
#include <sys/inotify.h>
int inotify_add_watch(int fd, const char *pathname, uint32_t mask);
## 參數(shù)
- fd: inotify_init的返回值;
- pathname: 目錄或文件路徑;
- mask: 監(jiān)控的事件類(lèi)型;
## 返回值
- 針對(duì)pathname的watch描述符

mask事件列表:

事件描述
IN_ACCESS文件被訪(fǎng)問(wèn)
IN_ATTRIB元數(shù)據(jù)被改變,例如權(quán)限、時(shí)間戳、擴(kuò)展屬性、鏈接數(shù)、UID、GID等
IN_CLOSE_WRITE打開(kāi)用于寫(xiě)的文件被關(guān)閉
IN_CREATE在監(jiān)控的目錄中創(chuàng)建了文件或目錄
IN_DELETE在監(jiān)控的目錄中刪除了文件或目錄
IN_DELETE_SELF監(jiān)控的文件或目錄本身被刪除
IN_CLOSE_NOWRITE不是打開(kāi)用于寫(xiě)的文件被關(guān)閉
IN_MODIFY文件被修改
IN_MOVE_SELF監(jiān)控的文件或目錄本身被移動(dòng)
IN_MOVED_FROM從監(jiān)控的目錄中移出文件
IN_MOVED_TO向監(jiān)控的目錄中移入文件
IN_OPEN文件或目錄被打開(kāi)
IN_ALL_EVENTS包含了上面提到的所有事件
  • 移除監(jiān)控對(duì)象
#include <sys/inotify.h>
int inotify_rm_watch(int fd, int wd);
## 參數(shù)值
- fd: inotify_init的返回值;
- wd: inotify_add_watch的返回值;

示例

  • 代碼示例
#include <iostream>
#include <thread>
#include <sys/inotify.h>
#include <sys/epoll.h>
#include <unistd.h>
using namespace std;
#define   INOTIFY_FDS           200
#define   INOTIFY_EVENT_SIZE    (sizeof(struct inotify_event))
#define   INOTIFY_BUF_LEN       (1024*(INOTIFY_EVENT_SIZE + 16))
int main()
{
	// inotify初始化
	int inotifyId = inotify_init();
	if (-1 == inotifyId)
	{
		cout << "inotify_init failed" << endl;
		return -1;
	}
	// 創(chuàng)建epoll句柄
	int epfd = epoll_create(INOTIFY_FDS);
	if (-1 == epfd)
	{
		cout << "epoll_create failed" << endl;
		return -1;
	}
	// 注冊(cè)epoll事件
	struct epoll_event ev;
	ev.data.fd = inotifyId;                
	ev.events = EPOLLIN | EPOLLET;      
	int ret = epoll_ctl(epfd, EPOLL_CTL_ADD, inotifyId, &ev);
	if (-1 == ret)
	{
		cout << "epoll_ctl failed" << endl;
		return -1;
	}
	// 添加監(jiān)聽(tīng)對(duì)象
	const char* pathMame = "/home/inotify/dir/";
	int watchFd = inotify_add_watch(inotifyId, pathMame, IN_MODIFY | IN_CREATE | IN_DELETE);
	if (watchFd < 0)
	{
		cout << "inotify_add_watch failed" << endl;
		return -1;
	}
	// 啟動(dòng)線(xiàn)程
	std::thread func = std::thread([&]() {
		// 循環(huán)監(jiān)聽(tīng)事件
		char buf[INOTIFY_BUF_LEN] = { 0, };
		struct epoll_event events[20];
		while (1)
		{
			int nfds = epoll_wait(epfd, events, 20, 1000);
			for (int i = 0; i < nfds; ++i)
			{
				if (events[i].data.fd != inotifyId)
				{
					continue;
				}
				int length = read(inotifyId, buf, INOTIFY_BUF_LEN);
				if (length < 0)
				{
					// error
					continue;
				}
				int pos = 0;
				while (pos < length)
				{
					struct inotify_event* event = (struct inotify_event*)&buf[pos];
					if (event->len)
					{
                        // 此處(event->wd == watchFd)
						if (event->mask & IN_CREATE)
						{
							if (event->mask & IN_ISDIR)
							{
								// dir create
								cout << "dir create" << endl;
							}
							else
							{
								// file create
								cout << "file create" << endl;
							}
						}
						else if (event->mask & IN_DELETE)
						{
							if (event->mask & IN_ISDIR)
							{
								// dir delete
								cout << "dir delete" << endl;
							}
							else
							{
								// file delete
								cout << "file delete" << endl;
							}
						}
						else if (event->mask & IN_MODIFY)
						{
							if (event->mask & IN_ISDIR)
							{
								// dir modify
								cout << "dir modify" << endl;
							}
							else
							{
								// file modify
								cout << "file modify" << endl;
							}
						}
					}
					pos += INOTIFY_EVENT_SIZE + event->len;
				}
			}
			// 1s更新一次
			sleep(1);
		}
	});
	func.join();
	while (1)
	{
		// 僅作事件循環(huán)
		sleep(2);
	}
	inotify_rm_watch(inotifyId, watchFd);
	close(epfd);
	close(inotifyId);
	return 0;
}
  • 執(zhí)行結(jié)果

[root@localhost inotify]# ./testInotify
file create
dir create
file create
file modify
file create
file modify
dir delete
file delete

到此這篇關(guān)于C++利用inotify+epoll實(shí)現(xiàn)異步文件監(jiān)控的方法的文章就介紹到這了,更多相關(guān)C++ inotify+epoll異步文件監(jiān)控內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)goto語(yǔ)句的用法

    C語(yǔ)言實(shí)現(xiàn)goto語(yǔ)句的用法

    goto語(yǔ)句通過(guò)關(guān)鍵字和標(biāo)簽實(shí)現(xiàn)跳轉(zhuǎn),常用于多層嵌套退出和資源清理,但易引發(fā)混亂代碼,本文就來(lái)詳細(xì)的介紹一下C語(yǔ)言實(shí)現(xiàn)goto語(yǔ)句的用法,感興趣的可以了解一下
    2025-09-09
  • VSCode配置C/C++語(yǔ)言環(huán)境(2023最新版)

    VSCode配置C/C++語(yǔ)言環(huán)境(2023最新版)

    這篇文章主要介紹了VSCode配置C/C++語(yǔ)言環(huán)境(2023最新版)的全過(guò)程,本文給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-11-11
  • 論C++的lambda是函數(shù)還是對(duì)象

    論C++的lambda是函數(shù)還是對(duì)象

    這篇文章主要介紹了論C++的lambda是函數(shù)還是對(duì)象,對(duì)于有捕獲的lambda,其等價(jià)于對(duì)象。對(duì)于沒(méi)有任何捕獲的lambda,其等價(jià)于函數(shù),下面來(lái)看看具體的相關(guān)內(nèi)容,需要的朋友可以參考一下
    2022-02-02
  • C++ Boost實(shí)現(xiàn)數(shù)字與字符串轉(zhuǎn)化詳解

    C++ Boost實(shí)現(xiàn)數(shù)字與字符串轉(zhuǎn)化詳解

    Boost是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱(chēng)。Boost庫(kù)是一個(gè)可移植、提供源代碼的C++庫(kù),作為標(biāo)準(zhǔn)庫(kù)的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開(kāi)發(fā)引擎之一,是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱(chēng)
    2022-11-11
  • C++字符數(shù)組、字符數(shù)組指針和string類(lèi)

    C++字符數(shù)組、字符數(shù)組指針和string類(lèi)

    這篇文章主要介紹了C++字符數(shù)組、字符數(shù)組指針和string類(lèi),string是一個(gè)類(lèi)而不是基本數(shù)據(jù)類(lèi)型,數(shù)組不含有處理函數(shù),下面更多詳細(xì)內(nèi)容,需要的小伙伴可以參考下面文章
    2022-03-03
  • C語(yǔ)言借助EasyX實(shí)現(xiàn)的生命游戲源碼

    C語(yǔ)言借助EasyX實(shí)現(xiàn)的生命游戲源碼

    這篇文章主要介紹了C語(yǔ)言借助EasyX實(shí)現(xiàn)的生命游戲的方法,需要的朋友可以參考下
    2014-07-07
  • 詳解C語(yǔ)言編程中預(yù)處理器的用法

    詳解C語(yǔ)言編程中預(yù)處理器的用法

    這篇文章主要介紹了C語(yǔ)言編程中預(yù)處理器的用法,包括介紹了C和C++混合編程的情況,需要的朋友可以參考下
    2016-02-02
  • C++中實(shí)現(xiàn)把表的數(shù)據(jù)導(dǎo)出到EXCEL并打印實(shí)例代碼

    C++中實(shí)現(xiàn)把表的數(shù)據(jù)導(dǎo)出到EXCEL并打印實(shí)例代碼

    這篇文章主要介紹了實(shí)現(xiàn)把表的數(shù)據(jù)導(dǎo)出到EXCEL并打印實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • 詳解C++的反調(diào)試技術(shù)與繞過(guò)手法

    詳解C++的反調(diào)試技術(shù)與繞過(guò)手法

    反調(diào)試技術(shù),惡意代碼會(huì)用它識(shí)別自身是否被調(diào)試,或者讓調(diào)試器失效,給反病毒工程師們制造麻煩,拉長(zhǎng)提取特征碼的時(shí)間線(xiàn),本章將具體總結(jié)常見(jiàn)的反調(diào)試基礎(chǔ)的實(shí)現(xiàn)原理以及如何過(guò)掉這些反調(diào)試手段,從而讓我們能夠繼續(xù)分析惡意代碼
    2021-06-06
  • linux下實(shí)現(xiàn)的2048游戲示例分享

    linux下實(shí)現(xiàn)的2048游戲示例分享

    這篇文章主要介紹了linux下實(shí)現(xiàn)的2048游戲示例,需要的朋友可以參考下
    2014-04-04

最新評(píng)論

霍林郭勒市| 剑河县| 洛隆县| 九龙坡区| 娄烦县| 香格里拉县| 沾益县| 宁德市| 濉溪县| 山阳县| 西城区| 赣榆县| 崇州市| 加查县| 义乌市| 德化县| 宁安市| 云南省| 大埔县| 东阿县| 尚志市| 辽阳市| 舞钢市| 开远市| 新和县| 韩城市| 柏乡县| 孟村| 仙桃市| 寿阳县| 安化县| 兴城市| 高唐县| 会泽县| 南丹县| 金川县| 永靖县| 图片| 清水县| 门源| 且末县|