inotify+selet實時不斷監測多個文件改動

不多說直接上代碼

void mian()
{	
	int fd[MONITOR_NUM];
	int wd[MONITOR_NUM];
	int count,i,j;
	int maxFd=0,readLen;
	//int len;

	char buf[EVENT_BUF_LEN] = {0};
	//the order of the two arrays is One-to-one correspondence.
	char monitorFile[3][WIRELESS_PROPERTY_NAME_LEN]={"/tmp/wifi_ch","/tmp/ch_list","/tmp/signal_q"};
	char prop[3][WIRELESS_PROPERTY_NAME_LEN]={"wifi_ch","ch_list","signal_q"};
	//struct inotify_event *event;
	fd_set fds;
	fd_set fds_use;
	FD_ZERO(&fds);

	printf("Wireless prop update thread running\n");

        for(i=0;i<MONITOR_NUM;i++)
	{
		/*
		*Try to init monitor the file three times,
		*if all fail,return.
		*/
		for (count = 0; count < 3; count++)
		{
			fd[i] = inotify_init();
			if (fd[i] < 0)
			{
				printf("inotify_init failed %d\n", count);
			}
			else
			{								
				break;
			}
		}
		if (count >= 3)
		{
			for(j=0;j<i;j++)
			{
				close(fd[j]);
			}
			FD_ZERO(&fds);
			return;
		}
		for (count = 0; count < 3; count++)
		{
			wd[i] = inotify_add_watch(fd[i], (char*)(&monitorFile[i][0]), IN_MODIFY);
			if (wd[i] < 0)
			{
				printf("inotify_add_watch %s failed %d\n", (char*)(&monitorFile[i][0]), count);
			}
			else
			{
				break;
			}
		}
		if (count >= 3)
		{
			for(j=0;j<i;j++)
			{
				inotify_rm_watch(fd[j], wd[i]);
				close(fd[j]);
			}
			FD_ZERO(&fds);
			return;
		}
	}

	for(count = 0; count < MONITOR_NUM; count++)
		{
			printf("fd:%d\n",fd[count]);
			if(fd[count]>maxFd) maxFd = fd[count];
			FD_SET(fd[count], &fds);				
		}

	for (;;)
	{
		
		printf("monitor run\n");
		fds_use=fds;
		if (select(maxFd + 1, &fds_use, NULL, NULL, NULL) > 0)
		{
			for(i=0;i<MONITOR_NUM;i++)
			{
				memset(buf, 0, EVENT_BUF_LEN);
				printf("before read:%d %d\n",i,maxFd);
				if(FD_ISSET(fd[i], &fds_use))
				{
					readLen=read(fd[i], buf, EVENT_BUF_LEN);			
					if(readLen > 0)
					{
						printf("after read\n");
						printf("path:%s modified\n", (char*)(&monitorFile[i][0]));
						p->processPropUpdate((char *)(&prop[i][0]));
					}
				}
			}
		}
	}

	for(i=0;i<MONITOR_NUM;i++)
	{
		inotify_rm_watch(fd[i], wd[i]);
		close(fd[i]);
	}
}

問題1:以上代碼是要監測三個文件的改動,但由於read被阻塞了,永遠在等待第一個文件的事件來臨,第一個不來,後面的永遠沒機會讀到。失去了原本的預想功能。

系統read函數調用,有可能因爲讀取對象是阻塞的而發生阻塞的情況,務必注意。

後來改用fd[i] = inotify_init1(IN_NONBLOCK);

就不阻塞了。
但出現了問題2:
同一個文件只監測一次事件,第二次過來就沒反應了。
只好每次監測到一次更改之後,重新初始化inotify,重走流程。還蠻難搞的。
記錄,以供參考。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章