Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!hellgate.utah.edu!cs.utexas.edu!uunet!virtech!cpcahil From: cpcahil@virtech.uucp (Conor P. Cahill) Newsgroups: comp.unix.wizards Subject: Re: Record locking vs. buffered I/O Summary: don't use buffered i/o with locking. Keywords: fcntl fread fwrite Message-ID: <1989Nov13.024420.738@virtech.uucp> Date: 13 Nov 89 02:44:20 GMT References: <1989Nov12.192441.9270@aucs.uucp> Organization: Virtual Technologies Inc. Lines: 48 In article <1989Nov12.192441.9270@aucs.uucp>, 850153d@aucs.uucp (Jules d'Entremont) writes: > I have the task of implementing a set of simple database routines. Since > there may be multiple processes accessing the database simultaneously, we > are using record locking (via the fcntl mechanism) to ensure data integrity. > However, the manual warns that buffering as done in stdio may cause > unexpected results. I understand that this results since the buffer may > not be written to the file before the lock is released. To get around this, > I use fflush() to flush the buffer before I release the lock. So my routine Not only that, but the entire buffered section will be written out to the file, thereby overwriting some portion of the file that you are not intending to write. If you are performing random access small reads and writes of data (as opposed to sequential reading/writing) you should use the read/write system calls not the stdio.h buffering. An fwrite() of x bytes followed by an ffush() will cause a write of at least 1 full stdio block (usually around 4k) and if the x # of bytes happens to straddle 2 blocks, you have 2 full blocks to write. Another complication of the fread/fwrite usage is that you must perform an fseek() before switching between the two. > for writing to the database has the following skeleton: > [ example code deleted... ] > fcntl(fileno(fptr), F_SETLK, &lock); /* Apply a shared lock */ Why place a shared lock on the entire file when performing a write operation. To gain maximum concurrency you should only place a write lock on the area of the file that you wish to update (set l_len to sizeof(datarec)). For reading, the same applies with the exception of the type of lock (shared) > I think this scheme should work, but I am not convinced. Is there a problem > with using buffered reads? Could the data read by fread() be incorrect because > of the buffering being done? Should I even be using buffered I/O at all? > (sizeof(data_record) = 24). No you should not be using buffered i/o for random accessing in this type of a file. -- +-----------------------------------------------------------------------+ | Conor P. Cahill uunet!virtech!cpcahil 703-430-9247 ! | Virtual Technologies Inc., P. O. Box 876, Sterling, VA 22170 | +-----------------------------------------------------------------------+