3

我有 2 个应用程序共享同一个锁定文件,我需要知道另一个应用程序何时锁定/解锁文件。下面的代码最初是在 Linux 机器上实现的,现在正在移植到 Window 8,VS12。

我已经成功移植了类中的所有其他代码,并且正在使用 LockFile(handle, 0, 0, sizeof(int), 0) 和等效的 UnlockFile(...) 锁定文件。但是,我在使用以下 wait() 命令时遇到了问题。

bool devices::comms::CDeviceFileLock::wait(bool locked,
                                           int  timeout)
{
   // Retrieve the current pid of the process.
   pid_t pid = getpid();

   // Determine if we are tracking time.
   bool tracking = (timeout > 0);

   // Retrieve the lock information.
   struct flock lock;
   if (fcntl(m_iLockFile, F_GETLK, &lock) != 0)
      raiseException("Failed to retrieve lock file information");

   // Loop until the state changes.
   time_t timeNow  = time(NULL);
   while ((pid == lock.l_pid) 
          &&
          (lock.l_type != (locked ? F_WRLCK : F_UNLCK)))
   {
      // Retrieve the lock information.
      if (fcntl(m_iLockFile, F_GETLK, &lock) != 0)
         raiseException("Failed to retrieve lock file information");

      // Check for timeout, if we are tracking.
      if (tracking)
      {
         time_t timeCheck = time(NULL);
         if (difftime(timeNow, timeCheck) > timeout)
            return false;
      }
   }

   // Return success.
   return true;
}

注意:m_iLockFile 曾经是来自 open() 的文件描述符,现在称为 m_hLockFile 并且是来自 CreateFile() 的 HANDLE。

我似乎找不到 fcntl F_GETLK 命令的 Windows 等效项。有谁知道我是否可以:a)使用等同于询问锁定信息的 fcntl,找出哪个进程获得了锁定 b)建议如何为 Windows C++ 重写上述内容。

注意:使用锁定文件的服务器应用程序是独立的 C++ 可执行文件,但使用锁定文件的客户端是 WinRT Windows 应用程序。所以任何建议的解决方案都不能破坏客户端的沙盒。

谢谢。

4

2 回答 2

4

你不会在 Windows 中找到它,它在多任务操作系统上根本不健全。您从 IsFileLocked() api 函数获得的值是没有意义的,另一个进程或线程仍然可以在一微秒后锁定文件。

解决方法很简单,如果您需要锁定,那么只需尝试获取一个。如果文件已经被锁定,那么 LockFile() 将简单地返回 FALSE,GetLastError() 会告诉你原因。现在它是原子的,是锁的基本属性。如果您有能力等待锁定,请使用不带 LOCKFILE_FAIL_IMMEDIATELY 选项的 LockFileEx()。

于 2013-07-18T12:32:29.847 回答
0

我只是在谷歌搜索你,但我发现了这个

“各种 C 语言运行时系统将 IOCTL 用于与 Windows 套接字无关的目的。因此,定义了 ioctlsocket 函数和WSAIoctl函数来处理由伯克利软件发行版中的IOCTL 和fcntl执行的套接字函数。”

这里也有一个简短的讨论——它是基于 python 的,但有一些线索。

于 2013-07-18T10:19:04.597 回答