Страница 1 из 2
Цикл или чтото другое?
Добавлено: 2009-08-26 13:03:13
mihan_k
Необходимо, к примеру, периодически опрашивать размер файла (лога), если размер изменяется, то производим занесение содержимого в базу данных , файл обнуляем и снова проверяем размер.
Каким образом можно реализовать? У меня есть мысли пока только с помощью цикла, но такой вариант даёт большую нагрузку на сервер и на жёсткий.
Re: Цикл или чтото другое?
Добавлено: 2009-08-26 13:07:38
paradox
и смотри например в сорусы утилиты tail
Re: Цикл или чтото другое?
Добавлено: 2009-08-26 13:18:05
mihan_k
Спасибо за сверхбыстрый ответ

, чувствую это на долго..
Re: Цикл или чтото другое?
Добавлено: 2009-08-26 15:43:26
mihan_k
Вот набросал такой код:
Код: Выделить всё
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;
}
Как теперь после изменения файла вывести сообщение и заного проверять его на изменение, чтобы не выходить из цикла?
Re: Цикл или чтото другое?
Добавлено: 2009-08-26 15:58:36
Sla
а зачем в цикле return?
Re: Цикл или чтото другое?
Добавлено: 2009-08-26 16:02:42
mihan_k
Ну вот я про это и спрашиваю, если убрать return, то выход из цикла не будет произведён, а начнёт постоянно выводиться сообщение "File was Writed!".
Надо как то обновить флаги и начать заного проверять файл на изменение.
Re: Цикл или чтото другое?
Добавлено: 2009-08-26 16:03:45
Sla
или
while(1) {
//здесь проверяешь размер файла
sleep(1);
};
Re: Цикл или чтото другое?
Добавлено: 2009-08-26 16:15:42
paradox
неправильный код
ты вообще не тот цикл крутишь
крутить нужно kevent
и man kevent
на возращаемые значения
Re: Цикл или чтото другое?
Добавлено: 2009-08-26 16:25:40
mihan_k
Приведи пример, если не сложно, я пока испытываю большие сложности с чтением man`ов.
Re: Цикл или чтото другое?
Добавлено: 2009-08-26 16:29:47
paradox
Код: Выделить всё
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;
}
Re: Цикл или чтото другое?
Добавлено: 2009-08-26 21:23:40
mihan_k
Всё сделал, работает, но почему сообщение "
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;
}
Re: Цикл или чтото другое?
Добавлено: 2009-08-26 21:47:39
paradox
а как вы в файл пишете?
возможно потому что открытие дексриптора на запись это первая запись
и запись данных это вторая запись
Re: Цикл или чтото другое?
Добавлено: 2009-08-26 21:49:52
mihan_k
Я просто открываю файл редактором ее, изменяю его и закрываю. В момент закрытия и сохранения выскакивает двойное сообщение.
Re: Цикл или чтото другое?
Добавлено: 2009-08-26 21:52:48
paradox
ну значит ee два раза пишет
попробуйте простой
должно поидеи один раз сработать
Re: Цикл или чтото другое?
Добавлено: 2009-08-26 21:55:12
mihan_k
Всё, извиняюсь, открывал при помощи mc F4, и при сохранении было двойное сообщение, а с ее всё ок.
Спасибо за помощь.
Re: Цикл или чтото другое?
Добавлено: 2009-08-28 18:25:23
mihan_k
Продолжу тему, интересует такой вопрос: каким образом я могу в той же программе выполнять какие-либо ещё функции попутно, причём эти функции должны работать не дожидаясь срабатывания события
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;
}
Re: Цикл или чтото другое?
Добавлено: 2009-08-28 18:33:41
paradox
установив таймаут ожидания kevent
man kevent
либо сделать дексриптор нонблок
Re: Цикл или чтото другое?
Добавлено: 2009-08-28 19:01:56
mihan_k
Получается, если установить таймаут, то можно упустить совершение события?
И можно поподробнее про дексриптор нонблок..
Re: Цикл или чтото другое?
Добавлено: 2009-08-28 19:10:33
paradox
Получается, если установить таймаут, то можно упустить совершение события?
нет
с какой радости?
это ж не магазин в котором если ушел с очереди вернулся а уже все разобрали
это как стол заказов
заказал и можешь ждать можешь не ждать
но когда прийдешь оно или будет лежать тебя ждать
или небудет тогда его еще и не было
И можно поподробнее про дексриптор нонблок..
долго рассказывать
попробуй погуглить
Re: Цикл или чтото другое?
Добавлено: 2009-08-28 20:26:13
mihan_k
Прикольно объясняешь

, меня устроит первый вариант.
Re: Цикл или чтото другое?
Добавлено: 2009-09-18 11:54:37
mihan_k
Переделал немного программу, добавил комментариев, чтобы примерно показать, на сколько мне понятна работа 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;
}
Re: Цикл или чтото другое?
Добавлено: 2009-09-18 12:35:09
paradox
EV_SET(&kev[2], fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, NOTE_WRITE, 0, 0);
это всего лиш макрос
а действие будет токо после kevent(.....)
Re: Цикл или чтото другое?
Добавлено: 2009-09-18 14:08:30
mihan_k
Всё получилось, оказывается не делал проверку на то, что файл уже удалён, из-за этого всё и сбивалось..
Ещё вопрос: обязательно ли делать 2 массива структур, чтобы в одном хранить сами события, а во второй выводить их результаты?
PS: как так набил больше 10 тыс. сообщений, а статус "проходил мимо" ))
Re: Цикл или чтото другое?
Добавлено: 2009-09-18 15:24:29
paradox
не понял насчет масива
а статус у меня персональный
Re: Цикл или чтото другое?
Добавлено: 2009-09-18 16:06:07
mihan_k
res = kevent(kq, kev, iNum, kevRes, iNumRes, &ts);
kev - содержит, допустим, 3 события, которые надо проверять.
kevRes - возвращаются результаты на происшедшие события.
Обязательно ли использовать kevRes или вместо него можно использовать kev?