3

同じロック ファイルを共有する 2 つのアプリケーションがあり、もう一方のアプリケーションがいつファイルをロックまたはロック解除したかを知る必要があります。以下のコードは、もともと 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() のハンドルです。

fcntl F_GETLK コマンドに相当する Windows が見つからないようです。次のいずれかができるかどうかは誰にもわかりますか?

注: ロック ファイルを使用するサーバー アプリケーションはスタンドアロンの C++ 実行可能ファイルですが、ロック ファイルを使用するクライアントは WinRT Windows アプリケーションです。したがって、提案されたソリューションは、クライアントのサンドボックス化を壊すことはできません。

ありがとう。

4

2 に答える 2

4

これは Windows では見られません。マルチタスク オペレーティング システムでは根本的に不適切です。IsFileLocked() api 関数から取得する値は無意味です。別のプロセスまたはスレッドが 1 マイクロ秒後にファイルをロックする可能性があります。

回避策は簡単です。ロックする必要がある場合は、ロックを取得してみてください。ファイルが既にロックされている場合、LockFile() は単純に FALSE を返します。GetLastError() はその理由を示します。今では、ロックの本質的なプロパティであるアトミックです。ロックを待つ余裕がある場合は、LOCKFILE_FAIL_IMMEDIATELY オプションを指定せずに LockFileEx() を使用してください。

于 2013-07-18T12:32:29.847 に答える
0

私はちょうどあなたのためにグーグルしていますが、私はこれを見つけまし

「さまざまな C 言語ランタイム システムは、Windows ソケットとは無関係の目的で IOCTL を使用します。その結果、ioctlsocket 関数とWSAIoctl関数は、バークレー ソフトウェア配布のIOCTL とfcntlによって実行されるソケット関数を処理するために定義されました。」

ここにも簡単な議論があります- これは python ベースですが、いくつかの手がかりがあります。

于 2013-07-18T10:19:04.597 に答える