1

使用 python,我有一个守护进程以下列方式监视日志文件:

f = open(r'logfile.log', 'r')
while True:
    line = f.readline()
    if not line:
      time.sleep(1)
    else:
      # do something

问题是,如果“做某事”部分是用 C 编写的,它的执行速度会快得多。所以,我想在 C 中做同样的事情。如何用 C 编写类似的跟踪日志文件的方法?

以下只是抓取整个文件,并对每一行执行“某些操作”。相反,我只想在日志文件中附加新行来“做某事”:)

  FILE *fr;
  char line[100];
  fr = fopen ("logfile.log", "rt");
  while(fgets(line, 100, fr) != NULL){
      //do something
  }
  fclose(fr);

谢谢!

4

3 回答 3

1

我最初的回答是:“在类似 POSIX 的系统上,您可以使用select()“观察”打开的文件描述符来查看是否有更多输入可用。这可能是在任何 Unix/Linux 系统上执行此操作的规范方式。”,但我错了

select()在套接字和管道上使用过,并假设它仅在有更多可用数据时才会返回,但这可能是肤浅的直觉,但实际上并非如此:select()定义为在后续read()(or write())不会阻塞时返回,这是另一回事,因为可以read()读取零字节而不是阻塞。

一个普通的文件总是read()可以的,即使在文件末尾也是如此。如果您尝试使用 跟踪日志文件select(),则select()从不阻塞,并且后续read()s 的长度为零。简而言之,你最终会忙于等待。阅读任何tail实现的源代码或阅读周围的讨论将证实这一点。

我想我应该把它留在这里,以防其他人犯同样的错误。

于 2013-09-18T19:55:32.863 回答
1

那么你可以试试下面的代码:

#include <stdio.h>
int main()
{
     mkfifo("tmpFifo");
     if(fork()==0)//to avoid the main program getting stuck at system()..
     {
          system("tail -f logfile.txt > tmpFifo");
          exit(0);
     }
     int fd = open("tmpFifo", O_RDONLY);
     char buff[1000];//set some length depending on the maximum string that gets 
                     //appended...
     int n;
     while((n=read(fd, buff, 1000))>0)
     {
         //do something... where 'n' stores the number of chars read...
     }
     close(fd);
     rm("tmpFifo");
     return 0;
}

如果您想编写代码而不是使用tail -f可能会有所帮助。但是,我想这是最简单的解决方案。

于 2013-09-18T15:40:32.037 回答
1

您可以使用该fseek功能跳到文件中的特定偏移量。为了避免跳过 Python 代码检测到的新行,python 中的部分应将查找偏移量传递给 C 代码。(最好的方法取决于你如何调用 C 代码..)

long seek_offset = /* get offset from Python side */
fseek(fr, seek_offset, SEEK_SET);
于 2013-09-18T15:33:01.163 回答