我有一个Job API的基本翻译,如下所示:
type
TJobObjectInfoClass = (
JobObjectBasicLimitInformation = 2,
JobObjectExtendedLimitInformation = 9
);
TJobObjectBasicLimitInformation = record
PerProcessUserTimeLimit: TLargeInteger;
PerJobUserTimeLimit: TLargeInteger;
LimitFlags: DWORD;
MinimumWorkingSetSize: DWORD;
MaximumWorkingSetSize: DWORD;
ActiveProcessLimit: DWORD;
Affinity: DWORD;
PriorityClass: DWORD;
SchedulingClass: DWORD;
end;
TIOCounters = record
ReadOperationCount: UInt64;
WriteOperationCount: UInt64;
OtherOperationCount: UInt64;
ReadTransferCount: UInt64;
WriteTransferCount: UInt64;
OtherTransferCount: UInt64;
end;
TJobObjectExtendedLimitInformation = record
BasicLimitInformation: TJobObjectBasicLimitInformation;
IoInfo: TIOCounters;
ProcessMemoryLimit: DWORD;
JobMemoryLimit: DWORD;
PeakProcessMemoryUsed: DWORD;
PeakJobMemoryUsed: DWORD;
end;
const
CREATE_BREAKAWAY_FROM_JOB = $01000000;
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE = $00002000;
function AssignProcessToJobObject(const hJob, hProcess: THandle): BOOL; stdcall;
external kernel32 name 'AssignProcessToJobObject';
function CreateJobObject(const lpJobAttributes: PSecurityAttributes;
const lpName: PChar): THandle; stdcall;
external kernel32 name {$IFDEF UNICODE}'CreateJobObjectW'{$ELSE}'CreateJobObjectA'{$ENDIF};
function SetInformationJobObject(const hJob: THandle;
const JobObjectInformationClass: TJobObjectInfoClass;
const lpJobObjectInformation: Pointer;
const cbJobObjectInformationLength: DWORD): BOOL; stdcall;
external kernel32 name 'SetInformationJobObject';
当我按如下方式使用它时,它可以正常工作:
Job := CreateJobObject(nil, nil);
if Job = 0 then
RaiseLastOSError;
ZeroMemory(@JELI, SizeOf(JELI));
JELI.BasicLimitInformation.LimitFlags := JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
Win32Check(SetInformationJobObject(
Job, JobObjectExtendedLimitInformation, @JELI, SizeOf(JELI))
);
由于我只设置了BasicLimitInformation
,因此我希望能够用SetInformationJobObject
来代替ZeroMemory(@JBLI, SizeOf(JBLI));
JBLI.LimitFlags := JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
Win32Check(SetInformationJobObject(
Job, JobObjectBasicLimitInformation, @JBLI, SizeOf(JBLI))
);
。
{{1}}
MSDN上的文档没有给我任何迹象表明这不受支持。那么为什么它失败了代码87(“参数不正确”)?
我最好的猜测是我的记录与Windows期望的结构不完全匹配,这意味着某些位在错误的位置。然而,当它嵌入另一个时,它工作正常。在那里,它是第一个字段,因此填充不太可能是原因。
答案 0 :(得分:0)
来自JOB_OBJECT_BASIC_LIMIT_INFORMATION
的文档:
[
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
]需要使用JOBOBJECT_EXTENDED_LIMIT_INFORMATION
结构。其BasicLimitInformation
成员是JOBOBJECT_BASIC_LIMIT_INFORMATION
结构。"
extended
结构以basic
结构开头,因此这两种结构至少部分兼容,这就是为什么你不能得到随机结果。
这应该给出正确的结果:
ZeroMemory(@JELI, SizeOf(JELI));
JELI.BasicLimitInformation.LimitFlags := JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
Win32Check(SetInformationJobObject(
Job, JobObjectBasicLimitInformation, @JELI, SizeOf(JELI))
);