Domanda

Ho un'applicazione Web di Delphi (Win32) che può essere eseguita sia come app CGI, ISAPI o Apache DLL. Voglio essere in grado di generare un prefisso di nome file univoco (univoco per tutte le richieste correnti in un determinato momento) e capire che il modo migliore per farlo sarebbe usare processID (per gestire la modalità CGI) e threadID (per gestire modalità dll).

Come posso ottenere un ID processo e un ID thread univoci in Delphi?

Saranno unici in una situazione multi-core / multiprocessore (su un singolo server web)?

Modifica: tieni presente che mi è stato sconsigliato questo approccio e quindi la risposta accettata utilizza un metodo diverso per generare nomi di file temporanei

È stato utile?

Soluzione

hai molte buone idee presentate qui.

  

Crea anche un file vuoto per " ottenere un blocco su " il nome?

no; credo che ci affidiamo a Windows per garantire che lo stesso nome di file temporaneo non venga mai assegnato due volte sullo stesso computer dal momento dell'avvio.

  

c'è qualche possibilità di uno scontro se c'è un ritardo di una frazione di secondo tra la generazione del nome e la creazione del file (se devo creare il file da solo).

no; sarebbe una brutta cosa.

ecco una routine che ho usato per ottenere un file temporaneo.

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;

puoi invece usare FileGetTempName () da JclFileUtils.pas in JCL.

Altri suggerimenti

Windows fornisce funzionalità per la creazione di nomi file univoci garantiti. Non è necessario crearne uno tuo:

Ecco un wrapper Delphi attorno a quella funzionalità:

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;

Non potresti invece utilizzare un GUID ?

Modifica: avrebbe dovuto essere detto per la prima volta, controlla le seguenti due funzioni

CreateGuid
GuidToString

Gli ID di processo non sono garantiti come univoci su Windows. Sono certamente unici per la vita del processo, ma una volta che un processo muore il suo ID può essere immediatamente riutilizzato. Non sono sicuro di ThreadIDs. Se questi sono file temporanei, potresti usare qualcosa di equivalente a tmpfile o tmpnam (funzioni C, ma suppongo che Delphi abbia un equivalente).

Dato che Jamie ha pubblicato un GUID potrebbe essere migliore.

1) Come ottenere un ID processo & amp; ThreadID in Delphi:

Risposta:
NOTA: assicurarsi di aggiungere "windows" alla clausola usi nella sezione di implementazione
NOTA: i cardinali sono numeri interi a 32 bit senza segno che vanno da 0 a 4294967295

implementation
uses Windows;

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

2) Saranno unici in una situazione multi-core / multi-processore (su una singola macchina web server)?
Risposta: Sì.

  

L'identificatore del processo è valido da   il tempo in cui il processo è stato creato fino al   il processo è stato terminato ed è   unico in tutto il sistema. (Non   unico per processore)

     

Fino al termine del thread, il   l'identificatore di thread identifica in modo univoco   il thread in tutto il sistema.   (Ancora una volta, a livello di sistema, non univoco per   processore)

Meglio di una di queste opzioni, dovresti usare la funzione di sistema _tempnam . Restituisce un nome file casuale nella directory per un file che non esiste. Se lo desideri, puoi fornire un prefisso a _tempnam in modo che il file che crei sia riconoscibilmente tuo. Se stai fornendo un prefisso univoco, non ci dovrebbero essere preoccupazioni per qualcuno che apre il tuo file. C'è un'altra soluzione, tuttavia.

_tempnam è utile solo se si desidera inserire il file in una directory arbitraria. Se non ti interessa che la directory sia la directory temporanea del sistema, utilizza tempfile_s invece. Creerà anche il file per te, quindi non preoccuparti delle condizioni di gara ... Gli errori si verificheranno solo se provi ad aprire più file temporanei di quelli che il sistema è in grado di gestire. Il grande svantaggio di tempfile_s è che il file scompare una volta chiuso.

EDIT: ho ottenuto un downvote perché questa è una funzione C. Hai accesso al runtime C importandoli in delphi. Dai un'occhiata ad alcuni esempi con msvcrt.dll qui .

function _tempnam(const Dir: PChar, const Prefix: PChar): PChar; cdecl;
  external 'msvcrt.dll' name '_tempnam';

Altri ti hanno dato idee valide e ragionevoli, ma comunque - se stai usando file per l'archiviazione temporanea e se quei file verranno sempre creati per primi (non importa se esiste un file rimanente con lo stesso nome già sul disco man mano che lo sovrascrivi comunque) l'approccio processid_threadid è completamente valido.

Usa GetCurrentProcessID e GetCurrentThreadID Win32 chiama per accedere a questi due ID.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top