是否有相当于在不同平台上进行预编译?

我在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平台来说, preadpread是任何支持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

上一篇: Are there equivalents to pread on different platforms?

下一篇: is MySql good for large databases?