Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I synchronize -- make atomic -- writes on one file from from two processes?

Tags:

c

atomic

I have two process each writing large buffer of data, and I want to control synchronize those processes' writes to one file.

process 1 writing buffer A including (A1, A2, A3) and process 2 writing buffer B including (B1, B2, B3). when we use write() system call to write these buffers to disk to the same file(whole buffer at one time: write(fd, A, sizeof(A))) , How is the file schema?

  • Is it like this: A, B or B, A maybe?
  • or it could be like this: A1, A2, B1, A3, ...

I'm asking this because system calls are atomic. what happens if the data buffer we are writing is too large. Is it like pipes for regular disk files?

like image 304
Majid Azimi Avatar asked Aug 01 '11 08:08

Majid Azimi


2 Answers

If you want the contents of both buffers to be present, you have to open the files with the O_APPEND flag set. The append flag seeks to the end of the file before writing. Without this set, it's possible that both processes will be pointing to the same or overlapping areas of the file and whoever writes last will overwrite what the other has written.

Each call to write will write up to the number of bytes requested. If your process is interrupted by a signal, then you can end up with a partial write -- the actual number of bytes written is returned. Whether you get all of your bytes written or not, you'll have written one contiguous section of the file. You don't get the interleaving effect you mentioned as your second possibility (e.g. A1,B1,A2,B2,...).

If you only get a partial write, how you proceed is up to you. You can either continue writing (offset from the buffer start by the number of bytes previously written), or you can abandon the rest of your write. Only in this way could you potentially get the interleaving effect.

If it's important to have the contents of one write complete before the other process writes, then you should look into locking the file for exclusive write access (which both processes will have to check for) before attempting to write any data.

like image 158
unpythonic Avatar answered Sep 30 '22 18:09

unpythonic


Assuming that the buffers are of equal size, the result will be either A or B, depending on which process was scheduled last.

The write system call is atomic, yes, meaning that the result will be either A or B, not a mixture of both.

Assuming that you want both A and B in the file, you can open the file with O_APPEND; note that this won't work over NFS, though.

Another option is that each process keeps track of which file offset it should use, and uses lseek() or pwrite()

like image 21
janneb Avatar answered Sep 30 '22 17:09

janneb