在Windows C++中查询哪个进程锁定了文件

3
我有两个应用程序共享同一个锁文件,我需要知道另一个应用程序何时锁定/解锁该文件。以下代码最初在Linux机器上实现,并被移植到Windows 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。
我无法找到 Windows 上等价于 fcntl F_GETLK 命令的函数。 有人知道是否可以: a)使用类似 fcntl 的函数来查询锁定信息,以查明哪个进程已获得了锁定 b)建议如何将上述代码重写适用于 Windows C++。
注意:使用锁文件的服务器应用程序是一个独立的 C++ 可执行文件, 但使用锁文件的客户端是 WinRT Windows 应用程序。因此,任何建议的解决方案都不能破坏客户端的沙箱环境。
谢谢。
2个回答

4
您在Windows中找不到这个功能,因为它在多任务操作系统上本质上是不稳定的。使用IsFileLocked() api函数得到的值是无意义的,因为另一个进程或线程仍然可以在微秒后锁定文件。
解决方法很简单,如果您需要锁定文件,请尝试获取锁。如果文件已被锁定,则LockFile()函数将返回FALSE,GetLastError()函数会告诉您原因。现在它是原子的,这是锁的一个必要属性。如果您可以等待锁,请使用LockFileEx()函数,并取消LOCKFILE_FAIL_IMMEDIATELY选项。

0

我正在为你谷歌搜索,但我找到了this

"各种C语言运行时系统使用IOCTL进行与Windows套接字无关的目的。因此,ioctlsocket函数和WSAIoctl函数被定义为处理由IOCTL和Berkeley软件分发中的fcntl执行的套接字函数。"

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


阅读WSAIoctl的文档,似乎只处理专门针对套接字而非文件的fcntl函数。它采用SOCKET而不是HANDLE作为其第一个参数。 - Marcus MacWilliam
不幸的是 - 我无法提供帮助,因此我会坐下来观看。祝你好运。 - doctorlove

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接