Date: Wed, 16 Jun 2021 19:12:54 -0400 From: Kurt Hackenberg <kh@panix.com> To: freebsd-questions@freebsd.org Subject: Re: Is a successful call to write(2) atomic? Message-ID: <af9666f4-f327-432e-5b10-100557aa9cf5@panix.com> In-Reply-To: <31698.1623883195@segfault.tristatelogic.com> References: <31698.1623883195@segfault.tristatelogic.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On 2021/06/16 18:39, Ronald F. Guilmette wrote: > The only reason I mention that is because I've just tried changing my > code so that the FD (#1) gets O_APPEND set on it at startup time and > then the calls to write() are wrapped in calls to flock() just as > John Levine and others suggested. Result? Output is still garbled. John Levine's sample code opened and closed the file around each write. Here is that code: fd = open("somefile", O_CREAT|O_WRONLY|O_APPEND); /* put some stuff in buf[] */ flock(fd, LOCK_EX); write(fd, buf, strlen(buf)): /* O_APPEND ensures it's added at the end */ flock(fd, LOCK_UN); Since you only open the file once, you should seek to end of file before each write, as somebody else pointed out. You should do that seek, and the write, while holding the file lock. That is: lock file seek to EOF write unlock file Does your code do that? The reason, of course, is that some other process could move end of file out from under you while you do not hold the file lock. > The one really odd thing about all of this is that I already have, and > have had, for a long time now, *many* programs that I've built and that > I have been using, also for a long time, that follow this same general > model, i.e. a parent a a lot of "worker bee" child processes where each > of the children, after completing a work item, does itself write a single > line of output, and *those* programs have all seemed to work flawlessly > (i.e. no output garbling) over a long period of time.... HOWEVER they > are all using the stdio functions to write to stdout, rather than > calling write() directly to write to FD #1. Those C library functions buffer the I/O operations within the user-mode process. The system calls don't do that. That C library buffering could change the internal details of concurrent access. > OK, so I tried swapping out calls to write() to call to fwrite()... > > Result: Some output lines still garbled. No surprise. You should lock the file, seek to end, write, unlock.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?af9666f4-f327-432e-5b10-100557aa9cf5>