如何在Delphi中获取唯一的Process ID和Thread ID?
在多核/多处理器情况下(在单个Web服务器机器上),它们是否会是唯一的?
请注意,我被建议不要采用这种方法,因此接受的答案使用了不同的方法来生成临时文件名。
你提出了很多好的想法。
它是否也会创建一个空文件以“锁定”名称?
不会;我相信我们依赖于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;
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;
在 Windows 上,进程 ID 不能保证唯一性。它们在进程的生命周期内肯定是唯一的,但一旦进程终止,其 ID 可能会立即被重用。我不确定线程 ID 是否也是如此。如果这些是临时文件,您可以使用类似于 tmpfile 或 tmpnam 的东西(C 函数,但我假设 Delphi 有等效函数)。
正如 Jamie 所发表的,GUID 可能更好。
1)如何在Delphi中获取唯一的进程ID和线程ID:
答案:
注意:确保在实现部分的uses子句中添加“windows”
注意:Cardinals是无符号32位整数,范围从0到4294967295
implementation
uses Windows;
procedure MySolution();
var
myThreadID:Cardinal;
myProcessID:Cardinal;
begin
myThreadID := windows.GetCurrentThreadID;
myProcessID := windows.GetCurrentProcessId;
end;
2) 在多核/多处理器情况下(在单个Web服务器机器上),这些标识符是否唯一?
答案:是。
进程标识符从创建进程开始到进程被终止期间有效,且在整个系统中是唯一的(不仅仅是唯一于处理器)。
线程标识符在线程终止之前唯一地识别整个系统中的线程。(同样,它在整个系统中是唯一的,而不是唯一于处理器)
function _tempnam(const Dir: PChar, const Prefix: PChar): PChar; cdecl;
external 'msvcrt.dll' name '_tempnam';
其他人都给了你很好和合理的建议,但是 - 如果你正在使用文件进行临时存储,并且如果这些文件将始终首先创建(如果磁盘上已经有一个同名的剩余文件也无所谓,因为你肯定会覆盖它),那么进程ID_线程ID方法是完全有效的。
使用 GetCurrentProcessID 和 GetCurrentThreadID Win32 调用来访问这两个 ID。