Цикл или чтото другое?

Модератор: Fastman

Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
mihan_k
мл. сержант
Сообщения: 70
Зарегистрирован: 2009-01-27 15:44:27

Цикл или чтото другое?

Непрочитанное сообщение mihan_k » 2009-08-26 13:03:13

Необходимо, к примеру, периодически опрашивать размер файла (лога), если размер изменяется, то производим занесение содержимого в базу данных , файл обнуляем и снова проверяем размер.
Каким образом можно реализовать? У меня есть мысли пока только с помощью цикла, но такой вариант даёт большую нагрузку на сервер и на жёсткий.

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Цикл или чтото другое?

Непрочитанное сообщение paradox » 2009-08-26 13:07:38

Код: Выделить всё

man kevent
и смотри например в сорусы утилиты tail

mihan_k
мл. сержант
Сообщения: 70
Зарегистрирован: 2009-01-27 15:44:27

Re: Цикл или чтото другое?

Непрочитанное сообщение mihan_k » 2009-08-26 13:18:05

Спасибо за сверхбыстрый ответ :), чувствую это на долго..

mihan_k
мл. сержант
Сообщения: 70
Зарегистрирован: 2009-01-27 15:44:27

Re: Цикл или чтото другое?

Непрочитанное сообщение mihan_k » 2009-08-26 15:43:26

Вот набросал такой код:

Код: Выделить всё

int main(int argc, char *argv[])
	{
	int kq = kqueue();
	int fd = open("/home/file.txt", O_RDONLY);
	struct kevent ke;
	EV_SET(&ke, fd, EVFILT_VNODE, EV_ADD, NOTE_WRITE, 0, NULL);
	kevent(kq, &ke, 1, NULL, 0, NULL);
	
	for (; ; )
		{
		if(ke.filter==EVFILT_VNODE && (ke.fflags&NOTE_WRITE))
			{
			cout << "File was Writed!\n";
			return 0;
			}
		}
	return 0;
	}
Как теперь после изменения файла вывести сообщение и заного проверять его на изменение, чтобы не выходить из цикла?

Sla
мл. сержант
Сообщения: 73
Зарегистрирован: 2008-08-19 15:09:19

Re: Цикл или чтото другое?

Непрочитанное сообщение Sla » 2009-08-26 15:58:36

а зачем в цикле return?

mihan_k
мл. сержант
Сообщения: 70
Зарегистрирован: 2009-01-27 15:44:27

Re: Цикл или чтото другое?

Непрочитанное сообщение mihan_k » 2009-08-26 16:02:42

Ну вот я про это и спрашиваю, если убрать return, то выход из цикла не будет произведён, а начнёт постоянно выводиться сообщение "File was Writed!".
Надо как то обновить флаги и начать заного проверять файл на изменение.

Sla
мл. сержант
Сообщения: 73
Зарегистрирован: 2008-08-19 15:09:19

Re: Цикл или чтото другое?

Непрочитанное сообщение Sla » 2009-08-26 16:03:45

или

while(1) {
//здесь проверяешь размер файла
sleep(1);
};

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Цикл или чтото другое?

Непрочитанное сообщение paradox » 2009-08-26 16:15:42

неправильный код
ты вообще не тот цикл крутишь
крутить нужно kevent
и man kevent
на возращаемые значения

mihan_k
мл. сержант
Сообщения: 70
Зарегистрирован: 2009-01-27 15:44:27

Re: Цикл или чтото другое?

Непрочитанное сообщение mihan_k » 2009-08-26 16:25:40

Приведи пример, если не сложно, я пока испытываю большие сложности с чтением man`ов.

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Цикл или чтото другое?

Непрочитанное сообщение paradox » 2009-08-26 16:29:47

Код: Выделить всё

int main(int argc, char *argv[])
{
int kq = kqueue();
int fd = open("/home/file.txt", O_RDONLY);
struct kevent ke;
int res;
  EV_SET(&ke, fd, EVFILT_VNODE, EV_ADD, NOTE_WRITE, 0, NULL);
  res = kevent(kq, &ke, 1, NULL, 0, NULL);


for (; ; )
{
    res = kevent(kq, .....) паметры из мануала

// вот сдесь нужно проверять значение res
// и в зависимости от него выходить из программы или делать свои действия
if(ke.filter==EVFILT_VNODE && (ke.fflags&NOTE_WRITE))
{
cout << "File was Writed!\n";
return 0;
}
}
return 0;
}

mihan_k
мл. сержант
Сообщения: 70
Зарегистрирован: 2009-01-27 15:44:27

Re: Цикл или чтото другое?

Непрочитанное сообщение mihan_k » 2009-08-26 21:23:40

Всё сделал, работает, но почему сообщение "File was Writed!" выводится 2 раза?
Вот код:

Код: Выделить всё

int main(int argc, char *argv[])
	{
	int res;
	int kq = kqueue();
	int fd = open("/home/file.txt", O_RDONLY);
	struct kevent ke;
	EV_SET(&ke, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, NOTE_WRITE, 0, 0);
	kevent(kq, &ke, 1, NULL, 0, NULL);
	for (;;)
		{
		res = kevent(kq, NULL, 0, &ke, 1, NULL);
		if(res>0 && (ke.fflags & NOTE_WRITE))
			{
			cout << "File was Writed!\n";
			}
		}
	return 0;
	}

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Цикл или чтото другое?

Непрочитанное сообщение paradox » 2009-08-26 21:47:39

а как вы в файл пишете?
возможно потому что открытие дексриптора на запись это первая запись
и запись данных это вторая запись

mihan_k
мл. сержант
Сообщения: 70
Зарегистрирован: 2009-01-27 15:44:27

Re: Цикл или чтото другое?

Непрочитанное сообщение mihan_k » 2009-08-26 21:49:52

Я просто открываю файл редактором ее, изменяю его и закрываю. В момент закрытия и сохранения выскакивает двойное сообщение.
Последний раз редактировалось mihan_k 2009-08-26 21:54:28, всего редактировалось 2 раза.

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Цикл или чтото другое?

Непрочитанное сообщение paradox » 2009-08-26 21:52:48

ну значит ee два раза пишет

попробуйте простой

Код: Выделить всё

echo "ddddd" >> file.txt
должно поидеи один раз сработать

mihan_k
мл. сержант
Сообщения: 70
Зарегистрирован: 2009-01-27 15:44:27

Re: Цикл или чтото другое?

Непрочитанное сообщение mihan_k » 2009-08-26 21:55:12

Всё, извиняюсь, открывал при помощи mc F4, и при сохранении было двойное сообщение, а с ее всё ок.
Спасибо за помощь.

mihan_k
мл. сержант
Сообщения: 70
Зарегистрирован: 2009-01-27 15:44:27

Re: Цикл или чтото другое?

Непрочитанное сообщение mihan_k » 2009-08-28 18:25:23

Продолжу тему, интересует такой вопрос: каким образом я могу в той же программе выполнять какие-либо ещё функции попутно, причём эти функции должны работать не дожидаясь срабатывания события res = kevent(kq, NULL, 0, &ke, 1, NULL);?

Код: Выделить всё

int main(int argc, char *argv[])
   {
   int res;
   int kq = kqueue();
   int fd = open("/home/file.txt", O_RDONLY);
   struct kevent ke;
   EV_SET(&ke, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, NOTE_WRITE, 0, 0);
   kevent(kq, &ke, 1, NULL, 0, NULL);
   for (;;)
      {
      res = kevent(kq, NULL, 0, &ke, 1, NULL);
      if(res>0 && (ke.fflags & NOTE_WRITE))
         {
         cout << "File was Writed!\n";
         }
      }
   return 0;
   }

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Цикл или чтото другое?

Непрочитанное сообщение paradox » 2009-08-28 18:33:41

установив таймаут ожидания kevent
man kevent

либо сделать дексриптор нонблок

mihan_k
мл. сержант
Сообщения: 70
Зарегистрирован: 2009-01-27 15:44:27

Re: Цикл или чтото другое?

Непрочитанное сообщение mihan_k » 2009-08-28 19:01:56

Получается, если установить таймаут, то можно упустить совершение события?

И можно поподробнее про дексриптор нонблок..

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Цикл или чтото другое?

Непрочитанное сообщение paradox » 2009-08-28 19:10:33

Получается, если установить таймаут, то можно упустить совершение события?
нет
с какой радости?
это ж не магазин в котором если ушел с очереди вернулся а уже все разобрали
это как стол заказов
заказал и можешь ждать можешь не ждать
но когда прийдешь оно или будет лежать тебя ждать
или небудет тогда его еще и не было
И можно поподробнее про дексриптор нонблок..
долго рассказывать
попробуй погуглить

mihan_k
мл. сержант
Сообщения: 70
Зарегистрирован: 2009-01-27 15:44:27

Re: Цикл или чтото другое?

Непрочитанное сообщение mihan_k » 2009-08-28 20:26:13

Прикольно объясняешь :), меня устроит первый вариант.

mihan_k
мл. сержант
Сообщения: 70
Зарегистрирован: 2009-01-27 15:44:27

Re: Цикл или чтото другое?

Непрочитанное сообщение mihan_k » 2009-09-18 11:54:37

Переделал немного программу, добавил комментариев, чтобы примерно показать, на сколько мне понятна работа kevent.
Вопрос состоит в следующем: как в процессе опроса событий добавлять ещё собития или удалять их, если они не нужны?
Если до инициализации Queue я составлял массив для опроса 2-3 файлов, то всё работает нормально, но когда уже программа работает, добавить новое событие не получается, так как всё сразу сбивается и опрос проходит неверно.
Вот код:

Код: Выделить всё

int main()
	{
	int	kq,
			iNum,		
			iNumRes,
			fd,
			res,		/* результат, количество произошечших событий */
			n;
	kq = kqueue();
	/* инициализируем структуры, знаем, что будем опрашивать всего 3 файла */
	struct kevent	kev[3],			/* тут будем регистрировать события */
						kevRes[3];	/* тут будем получать результаты от событий */
	struct timespec ts = { 1,0 };	/* устанавливаем время ожидания события в одну сек. */

	/* добавляем в описатели событий kev[0] и kev[1] последовательно 2 файла */
	/* проверять будем только на запись в файл */
	fd = open("/home/file1.txt", O_RDONLY);
	EV_SET(&kev[0], fd,	EVFILT_VNODE,	EV_ADD | EV_ENABLE | EV_CLEAR, NOTE_WRITE, 0, 0);
	fd = open("/home/file2.txt", O_RDONLY);
	EV_SET(&kev[1], fd,	EVFILT_VNODE,	EV_ADD | EV_ENABLE | EV_CLEAR, NOTE_WRITE, 0, 0);

	iNum=2;		/* опрашиваем пока 2 события */
	iNumRes=3;	/* всего событий будет 3 */

	int iNewFileExist=0; /* изначально 3-й файл не добавлен */

	for(;;)
		{
		res = kevent(kq, kev, iNum, kevRes, iNumRes, &ts);
		if(res>0)
			{
			for(n=0;n<res;n++)
				{
				if(kevRes[n].ident==kev[0].ident)) /* запись была произведена в file1.txt */
					{
					cout << "file1 was Writed!\n";
					}
				if(kevRes[n].ident==kev[1].ident)) /* запись была произведена в file2.txt */
					{
					cout << "file2 was Writed!\n";
					}
				if(iNewFileExist==1)		/* если 3-й файл был подключен, его тоже проверяем */
					if(kevRes[n].ident==kev[2].ident)) /* запись была произведена в file3.txt */
						{
						cout << "file3 was Writed!\n";
						}
				}
			}
		/* добавляем на проверку новый файл */
		if(iNewFileExist==0)
			{
			fd = open("/home/file3.txt", O_RDONLY);
			EV_SET(&kev[2], fd,	EVFILT_VNODE,	EV_ADD | EV_ENABLE | EV_CLEAR, NOTE_WRITE, 0, 0);
			iNum++;			/* увеличиваем количество проверяемых событий, теперь их 2 */
			iNewFileExist=1;	/* file3.txt добавлен на проверку */
			}
		}
	return 0;
	}

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Цикл или чтото другое?

Непрочитанное сообщение paradox » 2009-09-18 12:35:09

EV_SET(&kev[2], fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, NOTE_WRITE, 0, 0);
это всего лиш макрос
а действие будет токо после kevent(.....)

mihan_k
мл. сержант
Сообщения: 70
Зарегистрирован: 2009-01-27 15:44:27

Re: Цикл или чтото другое?

Непрочитанное сообщение mihan_k » 2009-09-18 14:08:30

Всё получилось, оказывается не делал проверку на то, что файл уже удалён, из-за этого всё и сбивалось..
Ещё вопрос: обязательно ли делать 2 массива структур, чтобы в одном хранить сами события, а во второй выводить их результаты?

PS: как так набил больше 10 тыс. сообщений, а статус "проходил мимо" ))

paradox
проходил мимо
Сообщения: 11620
Зарегистрирован: 2008-02-21 18:15:41

Re: Цикл или чтото другое?

Непрочитанное сообщение paradox » 2009-09-18 15:24:29

не понял насчет масива

а статус у меня персональный

mihan_k
мл. сержант
Сообщения: 70
Зарегистрирован: 2009-01-27 15:44:27

Re: Цикл или чтото другое?

Непрочитанное сообщение mihan_k » 2009-09-18 16:06:07

res = kevent(kq, kev, iNum, kevRes, iNumRes, &ts);

kev - содержит, допустим, 3 события, которые надо проверять.
kevRes - возвращаются результаты на происшедшие события.

Обязательно ли использовать kevRes или вместо него можно использовать kev?