On Tuesday 04 April 2006 11:49 am, Verdi March wrote:
Hi,
On Saturday 01 April 2006 21:56, Jerry Feldman wrote:
The location pointer should be atomic. I did not run a recent stress test on the 2.6 kernel. One of the problems is that you used streamIO, where the buffering is both in user space and underneath in kernel space. The system calls, open(2), dup(2), write(2), close(2) are atomic. And as I mentioned, they refer to the same single kernel open file structure. But, the streamIO functions are library functions and are not guaranteed to be atomic.
[deleted]
Another way is to write your own function using the vsprintf(3) function. I know that using a fixed size buffer here is unsafe, but I'm using it for the example. In the function, below, by using write(2) you are bypassing the stream's file structure (and its own location pointer).
I tried out your suggestion to bypass C stdio. I purposely open a file using O_WRONLY|O_CREAT|O_TRUNC only (no O_APPEND or O_DIRECT), then do the write without locking. The result, I can still get the race condition where both processes write from the beginning of the file. You should not get that under any case. char buf[SOME_SIZE]; fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC ); // create the empty file if (pid = fork()) == 0) { // child
sprintf(buf, "child pid is %d\n", getpid()); write(fd, buf, strlen(buf)); } else if (pid > 0) { // parent sprintf(buf, "Parent pid is %d\n", getpid()); write(fd, buf, strlen(buf)); } else { assert... } // both for(i = 0; i < 4; i++) { sprintf(buf, "%d: Iteration %d\n", getpid(), i); write(fd, buf, strlen(buf)); } close(fd); exit(0); } The file descriptor points to the same file structure, so that the location pointers should be correct. The race condition is simply who writes first, If you want you can either post your code or send me the code at gaf@hp.com
Looks like use either O_APPEND or application-level handling to guarantee that the race condition won't happen.
--
Jerry Feldman