我在多线程环境中几乎没有与read()/ pread()系统调用相关的查询
我正在使用基于freeBsd的Mac-OSX,如果这有任何帮助的话 我只在读模式下使用此文件,而不是读/写 语言是c / c ++
假设我们在磁盘上有一个文件 AAAABBBBCCCCDDDEEEE ....
和4个字母适合文件的一页
所以Page1:AAAA
2页:BBBB .....等等
现在我从具有相同文件描述符的两个不同线程启动读取系统调用 我的意图是从线程1读取第一页,从线程2读取第二页,等等。
读(FD,浅黄色,的sizeof(页));
从手册页我理解读取也会增加文件指针,所以我肯定会得到像#/ p>这样的乱码
ABCC ABBB ..等(没有特别的顺序)
要解决这个问题,我可以使用pread()
“Pread()执行相同的功能,但从speci中读取 在不修改文件指针“//从手册页
中修复文件中的位置但我不确定使用pread是否真的会帮助我实现目标,因为即使它没有增加内部文件指针,也无法保证响应不会混乱。
我的所有数据都是页面对齐的,我想从每个线程中读取一页,如
线程1读取:AAAA 线程2读取:BBBB 线程3读取:CCCC ...没有实际的内容..
我还找到了帖子Is it safe to read() from a file as soon as write() returns?
但它没有用。
我也不确定read()是否真的会有问题,我正在考虑。我正在阅读的文件是一个二进制文件,因此我很难快速手动阅读和验证..
任何帮助将不胜感激
答案 0 :(得分:9)
read
和write
更改基础打开文件的位置。它们是“线程安全的”,因为如果多个线程使用它们同时在同一个打开的文件上执行IO,那么您的程序将不会有未定义的行为(崩溃或更糟),但操作的顺序和原子性可能会有所不同,具体取决于文件类型和实现。
另一方面,pread
和pwrite
不会更改打开文件中的位置。它们被添加到POSIX中以达到您想要的目的:在多个线程或进程的同一个打开文件上执行IO操作,而不会使操作干扰彼此的位置。如果您将pread
和pwrite
(或多次调用pwrite
)与文件的重叠部分混合,您仍可能会遇到一些排序问题,但只要您避免这样做,他们对你想做的事情非常安全。
答案 1 :(得分:1)
fcntl
个顾问锁是该文件的范围上的锁。您可能会发现这对于序列化对同一区域的读取和写入非常有用,同时允许在不同的区域上进行并发。
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);
}
一次允许多个读取器锁定,而单个写入器锁定阻止所有其他锁定。
警告all file locking mechanisms are subtly broken on some configurations on all platforms。
答案 2 :(得分:-1)
在两个线程之间共享互斥锁,在线程读取之前启用锁定,并在正确读取完成后解锁锁定。请参阅pthread_mutex_create
,pthread_mutex_lock
和pthread_mutex_unlock
。