Is FileHandle safe to seek/read across multiple threads?

https://developer.apple.com/documentation/foundation/filehandle


I'm reading non-sequential bytes (random records) from a large file (hundreds of megabytes, low gigabytes) rapidly across several threads. Each thread may use a seek then read multiple times when reading records.


It is expensive constantly creating new FileHandle instances for each small read. I want to where possible reuse the same FileHandle instance without using locking to control access (I'm currently using locking to control access to shared FileHandle which works okay, but is not maximum performance...).


I want to avoid a race condition where one thread does a seek right before another does a read, changing the file offset in a shared FileHandler reader.


It appears that pread() handles this nicely:

http://man7.org/linux/man-pages/man2/pwrite.2.html


>> The pread() and pwrite() system calls are especially useful in

>> multithreaded applications. They allow multiple threads to perform

>> I/O on the same file descriptor without being affected by changes to

>> the file offset by other threads.


Is FileHandle opened via

init?(forReadingAtPath path: String)
safe to call the seek and read functions in this manner? i.e. does it use pread() under the hood and can I use a shared FileHandle instance across multiple threads for random reading without the file offset being hosed by another thread?

Replies

Whether the system uses pread/pwrite is considered an implementation detail. However, it doesn't really matter. You an open a file with FileHandle.init, and then use the POSIX file descriptor (there is a FileHandle method to access the POSIX file descriptor) in your own calls to pread/pwrite.

FileHandle isn't even safe for single-threaded reading! Depending on how clever you are, or are not, you might not notice any problems. But it sounds like you are starting to think cleverly, which is a bad thing to do with FileHandle. pread() is probably a good idea. Just get rid of the FileHandle.