LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Most efficient method to `monitor' for additions to a file ... in real-time (https://www.linuxquestions.org/questions/programming-9/most-efficient-method-to-%60monitor-for-additions-to-a-file-in-real-time-4175564103/)

Scraph 01-16-2016 08:58 AM

Most efficient method to `monitor' for additions to a file ... in real-time
 
The environment is Linux; language is C/C++; solar powered system so power is at a premium...

I have a file that is added to (as in, something is appended to the tail end) every 1 second. I need to identify, in a separate process, as soon data is added to the end of the file so that I can take action on it. The entire purpose of separate process is to monitor this file so the solution can be blocking.

What is the right way to do this?

The `dumb' ways I can think of involve infinite loops, sleep commands, and repeatedly trying to read ... but if I'm out of sync on my loop it can be nearly another second before I identify that data is available ... and the whole method just seems inefficient.

Is there a graceful way to identify exactly when new data is added to a file .. when that data is added once every ~1 second ... and I'm going to be monitoring this file 24/7?

Thanks for any suggestions!

TobiSGD 01-16-2016 09:37 AM

The Linux kernel provides the inotify subsystem exactly for this purpose. Short overview: http://linux.die.net/man/7/inotify

NevemTeve 01-16-2016 10:12 AM

Write a program, in which you open the file and read from it. Don't stop at eof, sleep a little then try reading again. Repeat infinitely.

Scraph 01-17-2016 09:54 AM

Thanks, TobiSGD! That's a great feature added to the Linux kernel ... it wasn't around last time I was coding on this platform. Very useful.

dugan 01-17-2016 10:21 AM

Consider using libuv, which supports monitoring filesystem events and which was used for both nodejs and neovim.

https://github.com/libuv/libuv

sundialsvcs 01-17-2016 10:53 AM

Quote:

Originally Posted by NevemTeve (Post 5479271)
Write a program, in which you open the file and read from it. Don't stop at eof, sleep a little then try reading again. Repeat infinitely.

I would suggest combining both of these approaches: instead of "busy waiting" to see if the file has been extended (which, actually, can be problematic if the file is "remote"), use some appropriate notification mechanism to allow the program to efficiently "sleep" until there might be more data available in the file.

Obviously, the cleanest approach would be to write the data to a pipe that is being read by a process which eventually writes the data to the permanent destination.

Scraph 01-18-2016 09:21 PM

I think the method I have settled on is using inotify if the input file is a regular file, using O_ASYNC and sigaction() to set up SIGIO for the inotify file-descriptor, and pause() while I wait for signals. If the input file is actually a pipe, I am simply setting up SIGIO to trigger ``I/O possible'' for the pipe, and again, using pause() while I wait.

I realize I could open the file in blocking mode and have read() block while I wait for input ... but there is also a network socket I am listening to ... so I don't want either the file or the socket blocking.

I saw some post somewhere where an `expert' said, ``if signals are your answer then you're asking the wrong question''... but I don't see how anything would be more appropriate for my application than pause() and SIGIO.

Thanks for the input, everyone.

ntubski 01-20-2016 07:20 AM

Quote:

Originally Posted by Scraph (Post 5480641)
I realize I could open the file in blocking mode and have read() block while I wait for input ... but there is also a network socket I am listening to ... so I don't want either the file or the socket blocking.

Sounds like a job for select(3) (or poll(3)).
EDIT: nevermind, won't work on files, as NevemTeve points out.

Although if you already have something working maybe "if it ain't broken don't fix it" applies...

NevemTeve 01-20-2016 07:36 AM

Yes, using select/poll is the usual method, except they don't work on disk-files (or so I was told).


All times are GMT -5. The time now is 04:46 PM.