read/pread 系统调用的线程安全
我有一些与多线程环境中的 read()
/pread()
系统调用相关的查询
我正在使用基于 freeBsd 的 Mac-OSX,如果这有帮助的话反正 我仅在读取模式下使用此文件,而不是读/写 语言是 c/c++
假设我们在磁盘上有一个文件:
AAAABBBBCCCCDDDEEEE ....
和 4 个字母适合文件的一页,
所以 Page1:AAAA
Page2:BBBB .....等等
现在我从具有相同文件描述符的两个不同线程发起读取系统调用。
我的目的是从线程 1 读取第一页,从线程 2 读取第二页,......等等。
read(fd,buff,sizeof(page));
从手册页中,我了解到 read 也会增加文件指针,所以我肯定会得到像
ABCC ABBB .. 等乱码响应(没有特定的序列)
来解决这个问题,我可以使用 pread()
来自手册页:
Pread() - 执行相同的功能,但从文件中的指定位置读取而不修改文件指针
但我不确定使用 pread 是否真的会帮助我实现我的目标,因为即使它不会增加内部文件指针,无法保证响应不会混乱。
我的所有数据都是页面对齐的,我想从每个线程读取一页,例如:
线程 1 读取:AAAA
线程 2 读取:BBBB
线程 3 读取:CCCC ...实际上没有混淆内容..
我还发现了一篇文章 write() 返回后立即从文件中 read() 安全吗?
但它不是很有用。
我也不确定 read()
是否真的会出现我正在考虑的问题。我正在读取的文件是一个二进制文件,因此快速手动读取和验证有点困难。
任何帮助将不胜感激
I have few queries related to read()
/pread()
system calls in a multi-threaded 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 intention 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()
From man pages:
Pread() - performs the same function, but reads from the specified position in the file without modifying the file pointer
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 wasn't quite useful .
I am also not sure whether read()
will actually have the problem, that I am thinking of. The file that I am reading is a binary file and hence it is a little difficult to just quickly manually read and verify..
Any help will be appreciated
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
read
和write
更改底层打开文件的位置。它们是“线程安全”的,因为如果多个线程同时使用它们在同一个打开的文件上执行 IO,您的程序不会出现未定义的行为(崩溃或更糟),但操作的顺序和原子性可能会有所不同,具体取决于文件类型和实现。另一方面,
pread
和pwrite
不会更改打开文件中的位置。它们被添加到 POSIX 中正是为了您想要的目的:从多个线程或进程对同一个打开的文件执行 IO 操作,而操作不会干扰彼此的位置。如果您将pread
和pwrite
(或多次调用pwrite
)与重叠部分混合使用,您仍然可能会遇到一些排序问题。文件,但只要你避免这种情况,它们对于你想做的事情来说是完全安全的。read
andwrite
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
andpwrite
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 mixingpread
andpwrite
(or multiple calls topwrite
) with overlapping parts of the file, but as long as you avoid that, they're perfectly safe for what you want to do.fcntl
咨询锁是对文件范围的锁定。您可能会发现这对于序列化对同一区域的读取和写入同时允许不同区域上的并发非常有用。一次允许多个读取器锁定,而单个写入器锁定会阻止所有其他锁定。
请注意,所有文件锁定机制在所有平台上的某些配置上都会被巧妙地破坏。
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.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.
两个线程之间共享一个互斥锁,在读取之前启用线程中的锁,并在正确读取完成时解锁该锁。请参阅
pthread_mutex_create
、pthread_mutex_lock
和pthread_mutex_unlock
。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
, andpthread_mutex_unlock
.