是否有相当于在不同平台上进行预编译?
我在C ++中编写了一个并发的持久消息队列,它需要对文件进行并发读取访问而不使用内存映射io。 简短的故事是,几个线程将需要从文件的不同偏移中读取。
最初我有一个具有典型读/写方法的文件对象,并且线程将获得一个互斥体来调用这些方法。 然而,恰巧我没有正确地获取互斥锁,导致一个线程在读/写期间移动文件偏移量,另一个线程开始读取/写入文件的错误部分。
所以,偏执的解决方案是每个线程都有一个打开的文件句柄。 现在我对同一个文件有很多文件句柄,我认为它不会很好。
我想使用像pread这样的东西,它允许将当前偏移量传入读取/写入函数。
然而,该功能只在Linux上可用,我需要Windows,aix,solaris和hpux上的等效实现,有什么建议吗?
在Windows上,ReadFile()函数可以执行此操作,请参阅lpOverlapped
参数和异步IO上的此信息。
使用NIO, java.nio.channels.FileChannel
有一个read(ByteBuffer dst, long position)
方法,它在内部使用pread
。
哦,等等,你的问题是关于C ++,而不是Java。 那么,我只是看了看JDK源代码,看看它是如何用于Windows的,但不幸的是,在Windows上它不是原子的:它只是查找,然后读取,然后找回。
对于Unix平台来说, pread
是pread
是任何支持XSI(X / Open System Interface,显然)操作系统的标准:http://www.opengroup.org/onlinepubs/009695399/functions/pread.html
基于另一个答案,我能想出最接近的就是这个。 但是,有一个错误:ReadFile将更改文件偏移量,并且pread保证不会更改文件偏移量。 没有真正的解决方法,因为代码可以在不锁定的情况下正常执行read()和write()。 有人发现一个不会改变偏移量的调用?
unsigned int FakePRead(int fd, void *to, std::size_t size, uint64_offset) {
// size_t might be 64-bit. DWORD is always 32.
const std::size_t kMax = static_cast<std::size_t>(1UL << 31);
DWORD reading = static_cast<DWORD>(std::min<std::size_t>(kMax, size));
DWORD ret;
OVERLAPPED overlapped;
memset(&overlapped, 0, sizeof(OVERLAPPED));
overlapped.Offset = static_cast<DWORD>(off);
overlapped.OffsetHigh = static_cast<DWORD>(off >> 32);
if (!ReadFile((HANDLE)_get_osfhandle(fd), to, reading, &ret, &overlapped)) {
// TODO: set errno to something?
return -1;
}
// Note the limit to 1 << 31 before.
return static_cast<unsigned int>(ret);
}
链接地址: http://www.djcxy.com/p/19751.html