thread safety of read/pread system calls
I have few queries related to read()/pread() system calls in a multithreaded environment
I am using Mac-OSX which is freeBsd based , if that helps in any way I am only using this file in read mode,and not read/write And the language is c/c++
Suppose we have a file on disk AAAABBBBCCCCDDDEEEE....
and 4 alphabets fit on one page of the file
So Page1:AAAA
Page2:BBBB ..... and so on
now i initiate a read system call from two different threads with the same file descriptor my intension is to read first page from thread 1, second page from thread 2,..and so on.
read(fd,buff,sizeof(page));
From the man page i am given to understand that read will also increment the file pointer ,so definitely i am gonna get garbled responses like
ABCC ABBB .. etc (with no particular sequence )
to remedy this i can use pread()
"Pread() performs the same function, but reads from the speci- fied position in the file without modifying the file pointer" // from man pages
But i am not sure whether using pread will actually help me in my objective , cause even though it does not increment the internal file pointer , there are no guarantees that the responses are not jumbled.
All of my data is page aligned and i want to read one page from each thread like
Thread 1 reads:AAAA Thread 2 reads:BBBB Thread 3 reads:CCCC ... without actually garbling the content ..
I also found a post Is it safe to read() from a file as soon as write() returns?
but it wasnt quite useful .
I am also not sure whether read() will actu开发者_开发技巧ally have the problem, that i am thinking of.The file that i am reading is a binary file and hence i litle difficult to just quickly manually read and verify..
Any help will be appreciated
read
and write
change the position of the underlying open file. They are "thread safe" in the sense that your program will not have undefined behavior (crash or worse) if multiple threads perform IO on the same open file at once using them, but the order and atomicity of the operations could vary depending on the type of file and the implementation.
On the other hand, pread
and pwrite
do not change the position in the open file. They were added to POSIX for exactly the purpose you want: performing IO operations on the same open file from multiple threads or processes without the operations interfering with one another's position. You could still run into some trouble with ordering if you're mixing pread
and pwrite
(or multiple calls to pwrite
) with overlapping parts of the file, but as long as you avoid that, they're perfectly safe for what you want to do.
fcntl
advisory locks are locks on a range of the file. You may find this useful to serialize reads and writes to the same region while allowing concurrency on separate regions.
int rc;
struct flock f;
f.l_type = F_RDLCK; /* or F_WRLCK */
f.l_whence = SEEK_SET;
f.l_start = n;
f.l_len = 1;
while ((rc = fcntl(fd, F_SETLKW, &f)) == -1 && errno = EINTR)
;
if (rc == -1)
perror("fcntl(F_SETLKW)");
else {
/* do stuff */
f.l_type = F_UNLCK;
fcntl(fd, F_SETLK, &f);
}
Multiple reader locks are permitted at a time, while a single writer lock blocks all others.
Be warned that all file locking mechanisms are subtly broken on some configurations on all platforms.
Share a mutex lock between the two threads, enable the lock in the thread before it reads, and unlock the lock when the correct read is complete. See pthread_mutex_create
, pthread_mutex_lock
, and pthread_mutex_unlock
.
精彩评论