Depends on how you define "efficient". If you're asking about performance the difference is microscopic. So use the one that solves the problem for you. In many cases pread
is the only option when you're dealing with threads reading from a database or such. In other cases read
is the only sensible option. And the question is a little bit unfair since pread
does more than read
. A fair comparison would be lseek
+ read
which will definitely be slower than just pread
.
Let's look at the differences in implementation of both in an operating system source I had available. I cut out the exact same code from both functions to highlight the differences. There's much more code than this.
This is part of pread
:
vp = (struct vnode *)fp->f_data;
if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO ||
(vp->v_flag & VISTTY)) {
return (ESPIPE);
}
offset = SCARG(uap, offset);
if (offset < 0 && vp->v_type != VCHR)
return (EINVAL);
return (dofilereadv(p, fd, fp, &iov, 1, 0, &offset, retval));
This is the equivalent part of read
:
return (dofilereadv(p, fd, fp, &iov, 1, 0, &fp->f_offset, retval));
So, pread
does some extra checks to make sure that we're not trying to seek on a pipe, fifo, tty, etc. And it checks that we're not reading a negative offset from a character device. It also doesn't update the offset in the file pointer (fp
in the code).