Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

non blocking write to file in c/c++

Tags:

c++

c

I'm writing a logging program, and I need to read from serial once a second then print to a log file. The problem is that sometimes, something is holding up my loop and data is getting backed up. After timing every activity in my loop, I noticed that the function that prints my data to the log file is the one taking up too much time sometimes. I was looking into non-blocking write to file, and according to this post:

File writing with overlapped IO vs file writing in a separate thread

The "write to files" should not be blocking my program by default. But it seems like they are.

I'm using MS visual studio EX and I'm writing a consol c++ app. Can someone tell me if fprintf and << are supposed to be non-blocking/asynchronous by default? If not, is there a way to make them so?

like image 698
Siavash Avatar asked Dec 13 '10 22:12

Siavash


1 Answers

Here is how things work in Linux:

Writes/reads to/from regular files can't not be made blocking because of kernel buffering. When the kernel runs out of memory for buffering, however, they will block.

From The Linux Programming Interface: A Linux and UNIX System Programming Handbook:

Nonblocking mode can be used with devices (e.g., terminals and pseudoterminals), pipes, FIFOs, and sockets. (Because file descriptors for pipes and sockets are not obtained using open(), we must enable this flag using the fcntl() F_SETFL operation described in Section 5.3.)

O_NONBLOCK is generally ignored for regular files, because the kernel buffer cache ensures that I/O on regular files does not block, as described in Section 13.1. However, O_NONBLOCK does have an effect for regular files when mandatory file locking is employed (Section 55.4).

From Advanced Programming in the UNIX Environment 2nd Ed:

We also said that system calls related to disk I/O are not considered slow, even though the read or write of a disk file can block the caller temporarily.

From http://www.remlab.net/op/nonblock.shtml:

Regular files are always readable and they are also always writeable. This is clearly stated in the relevant POSIX specifications. I cannot stress this enough. Putting a regular file in non-blocking has ABSOLUTELY no effects other than changing one bit in the file flags.

Reading from a regular file might take a long time. For instance, if it is located on a busy disk, the I/O scheduler might take so much time that the user will notice the application is frozen.

Nevertheless, non-blocking mode will not work. It simply will not work. Checking a file for readability or writeability always succeeds immediately. If the system needs time to perform the I/O operation, it will put the task in non-interruptible sleep from the read or write system call.

like image 96
Patrick Pan Avatar answered Sep 28 '22 10:09

Patrick Pan