3

CGI アプリ、ISAPI、または Apache DLL として実行できる Delphi (Win32) Web アプリケーションがあります。一意のファイル名プレフィックス (特定の時点での現在のすべての要求に対して一意) を生成できるようにしたいのですが、これを行う最善の方法は、processID (CGI モードを処理するため) と threadID (処理するため) を使用することであると考えています。 dll モード)。

Delphi で一意のプロセス ID とスレッド ID を取得するにはどうすればよいですか?

これらは、マルチコア/マルチプロセッサの状況 (単一の Web サーバー マシン上) で一意になりますか?

編集:私はこのアプローチに反対するようにアドバイスされたことに注意してください。したがって、受け入れられた回答は別の方法を使用して一時的なファイル名を生成します

4

7 に答える 7

5

ここに提示された多くの良いアイデアがあります。

名前を「ロックする」ために空のファイルも作成しますか?

番号; 起動時以降、同じ一時ファイル名が同じコンピューターで 2 回与えられないようにするために、Windows に依存していると思います。

名前の生成とファイルの作成の間に一瞬の遅延がある場合、衝突の可能性はありますか (ファイルを自分で作成する必要がある場合)。

番号; それはかなり悪いことです。

これは、一時ファイルを取得するために使用してきたルーチンです。

function GetTemporaryFileName:string;
var
  Path, FileName: array[0..MAX_PATH] of Char;
begin
  Win32Check(GetTempPath(MAX_PATH, Path) <> 0);
  Win32Check(GetTempFileName(Path, '~EX', 0, FileName) <> 0);
  Result:=String(Filename);
end;

代わりに、JCL で JclFileUtils.pas の FileGetTempName( ) を使用できます。

于 2008-11-07T17:46:31.240 に答える
5

Windows は、保証された一意のファイル名を作成する機能を提供します。独自に作成する必要はありません:

その機能の Delphi ラッパーを次に示します。

function CreateTempFileName(aPrefix: string): string;
var
  Buf: array[0..MAX_PATH] of Char;
  Temp: array[0..MAX_PATH] of Char;
begin
  GetTempPath(MAX_PATH, Buf);
  if GetTempFilename(Buf, PChar(aPrefix), 0, Temp) = 0 then
  begin
    raise Exception.CreateFmt(sWin32Error, [GetLastError, SysErrorMessage(GetLastError)]);
  end;
  Result := string(Temp);
end;
于 2008-11-08T04:29:38.337 に答える
4

代わりに GUIDを使用できませんか?

編集:最初に言ったはずですが、次の2つの機能をチェックしてください

CreateGuid
GuidToString
于 2008-11-07T17:13:11.697 に答える
3

1)Delphiで一意のプロセスIDとスレッドIDを取得する方法:

回答:
注:実装セクションのuses句に「windows」を追加してください。
注:Cardinalsは、0〜4294967295の範囲の符号なし32ビット整数です。

implementation
uses Windows;

procedure MySolution();
var
  myThreadID:Cardinal;  
  myProcessID:Cardinal;
begin
  myThreadID := windows.GetCurrentThreadID;
  myProcessID := windows.GetCurrentProcessId;
end;

2)これらはマルチコア/マルチプロセッサの状況(単一のWebサーバーマシン上)で一意ですか?
回答:はい。

プロセス識別子は、プロセスが作成されてから終了するまで有効であり、システム全体で一意です。(プロセッサに固有ではありません)

スレッドが終了するまで、スレッド識別子はシステム全体でスレッドを一意に識別します。(繰り返しますが、システム全体で、プロセッサに固有のものではありません)

于 2008-11-08T03:47:48.767 に答える
3

プロセス ID は、Windows 上で一意であるとは限りません。それらはプロセスの存続期間中は確かに一意ですが、プロセスが終了すると、その ID はすぐに再利用できます。ThreadID についてはよくわかりません。これらが一時ファイルの場合、tmpfile または tmpnam と同等のものを使用できます (C 関数ですが、Delphi には同等のものがあると思います)。

Jamie が投稿したように、GUID の方がよい場合があります。

于 2008-11-07T17:15:19.277 に答える
2

これらのオプションのいずれよりも優れているのは、システム関数_tempnamを使用することです。存在しないファイルのディレクトリにランダムなファイル名を返します。必要に応じて、_tempnam にプレフィックスを付けて、作成したファイルが自分のものであることを認識できるようにすることができます。一意のプレフィックスを提供している場合、誰かがあなたのファイルを開く心配はありません。ただし、別の解決策があります。

_tempnam は、ファイルを任意のディレクトリに配置する場合にのみ有効です。ディレクトリがシステムの一時ディレクトリであることを気にしない場合は、代わりにtempfile_sを使用してください。また、ファイルを作成するので、競合状態の心配はありません... システムが処理できる以上の一時ファイルを開こうとした場合にのみ、エラーが発生します。tempfile_s の大きな欠点は、ファイルを閉じると消えてしまうことです。

編集:これはC関数であるため、反対票を投じました。Delphi にインポートすることで、C ランタイムにアクセスできます。ここで msvcrt.dll の例をいくつか見てみましょう。

function _tempnam(const Dir: PChar, const Prefix: PChar): PChar; cdecl;
  external 'msvcrt.dll' name '_tempnam';
于 2008-11-07T17:19:30.360 に答える
1

他の人はすべてあなたに良い合理的なアイデアを与えましたが、それでも-一時的なストレージにファイルを使用していて、それらのファイルが常に最初に作成される場合(同じ名前の残りのファイルが既にとにかく上書きするので)、processid_threadidアプローチは完全に有効です。

GetCurrentProcessIDおよびGetCurrentThreadID Win32 呼び出しを使用して、これら 2 つの ID にアクセスします。

于 2008-11-07T17:40:14.733 に答える