正在写一个oj系统,对于Job作业对象的一些功能看不懂,《windows核心编程》也是一笔带过……无奈中这是《windows核心编程》上的example,我改了一下。其中test.file.exe的作用仅仅是停5秒钟,但是获得的时间通常小于20ms。不解
GetLasterror出来1812……。。#include <iostream>
#include <cstdio>
#define _WIN32_WINNT 0x0601
#include <windows.h>
using namespace std;
void StartRestrictedProcess()
{
// Check if we are not already associated with a job.
// If this is the case, there is no way to switch to
// another job. // Create a job kernel object.
HANDLE hjob = CreateJobObject(NULL,
"Wintellect_RestrictedProcessJob");
// Place some restrictions on processes in the job.
// First, set some basic restrictions.
JOBOBJECT_BASIC_LIMIT_INFORMATION jobli = { 0 };
// The process always runs in the idle priority class.
jobli.PriorityClass = IDLE_PRIORITY_CLASS;
// The job cannot use more than 1 second of CPU time.
jobli.PerJobUserTimeLimit.QuadPart = 10000000; // 1 sec in 100-ns intervals
// These are the only 2 restrictions I want placed on the job (process).
jobli.LimitFlags = JOB_OBJECT_LIMIT_PRIORITY_CLASS
| JOB_OBJECT_LIMIT_JOB_TIME;
SetInformationJobObject(hjob, JobObjectBasicLimitInformation, &jobli,
sizeof(jobli));
// Second, set some UI restrictions.
JOBOBJECT_BASIC_UI_RESTRICTIONS jobuir;
jobuir.UIRestrictionsClass = 0; // A fancy zero
// The process can't log off the system.
jobuir.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_EXITWINDOWS;
// The process can't access USER objects (such as other windows)
// in the system.
jobuir.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES;
SetInformationJobObject(hjob, JobObjectBasicUIRestrictions, &jobuir,
sizeof(jobuir));
// Spawn the process that is to be in the job.
// Note: You must first spawn the process and then place the process in
// the job. This means that the process’ thread must be initially
// suspended so that it can’t execute any code outside of the job's
// restrictions.
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
BOOL bResult =
CreateProcess(
NULL, (char *)"file.test.exe", NULL, NULL, FALSE,
CREATE_SUSPENDED | CREATE_NEW_CONSOLE | CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &si, &pi);
cerr<<bResult<<endl;
// Place the process in the job.
// Note: If this process spawns any children, the children are
// automatically part of the same job.
bResult = AssignProcessToJobObject(hjob, pi.hProcess);
cerr<<bResult<<endl;
cerr<<GetLastError()<<endl;
// Now we can allow the child process' thread to execute code.
ResumeThread(pi.hThread);
CloseHandle(pi.hThread);
// Wait for the process to terminate or
// for all the job's allotted CPU time to be used.
HANDLE h[2];
h[0] = pi.hProcess;
h[1] = hjob;
DWORD dw = WaitForMultipleObjects(2, h, FALSE, INFINITE);
switch (dw - WAIT_OBJECT_0)
{
case 0:
// The process has terminated...
break;
case 1:
// All of the job's allotted CPU time was used...
break;
}
LARGE_INTEGER CreationTime;
LARGE_INTEGER ExitTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime; GetProcessTimes(pi.hProcess, (LPFILETIME)&CreationTime, (LPFILETIME)&ExitTime,
(LPFILETIME)&KernelTime, (LPFILETIME)&UserTime);
printf("Kernel = %u | User = %u\n", KernelTime.QuadPart / 100000, UserTime.QuadPart / 100000);
//MessageBox(GetActiveWindow(), szInfo, "Restricted Process times",
// MB_ICONINFORMATION | MB_OK);
// Clean up properly.
CloseHandle(pi.hProcess);
CloseHandle(hjob);
}
int main(void)
{
StartRestrictedProcess();
return 0;
}
另外求解如何限制job中进程不允许读写文件、关闭计算机(也就是问JOBOBJECT_SECURITY_LIMIT_INFORMATION 的各个参数和作用)
GetLasterror出来1812……。。#include <iostream>
#include <cstdio>
#define _WIN32_WINNT 0x0601
#include <windows.h>
using namespace std;
void StartRestrictedProcess()
{
// Check if we are not already associated with a job.
// If this is the case, there is no way to switch to
// another job. // Create a job kernel object.
HANDLE hjob = CreateJobObject(NULL,
"Wintellect_RestrictedProcessJob");
// Place some restrictions on processes in the job.
// First, set some basic restrictions.
JOBOBJECT_BASIC_LIMIT_INFORMATION jobli = { 0 };
// The process always runs in the idle priority class.
jobli.PriorityClass = IDLE_PRIORITY_CLASS;
// The job cannot use more than 1 second of CPU time.
jobli.PerJobUserTimeLimit.QuadPart = 10000000; // 1 sec in 100-ns intervals
// These are the only 2 restrictions I want placed on the job (process).
jobli.LimitFlags = JOB_OBJECT_LIMIT_PRIORITY_CLASS
| JOB_OBJECT_LIMIT_JOB_TIME;
SetInformationJobObject(hjob, JobObjectBasicLimitInformation, &jobli,
sizeof(jobli));
// Second, set some UI restrictions.
JOBOBJECT_BASIC_UI_RESTRICTIONS jobuir;
jobuir.UIRestrictionsClass = 0; // A fancy zero
// The process can't log off the system.
jobuir.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_EXITWINDOWS;
// The process can't access USER objects (such as other windows)
// in the system.
jobuir.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES;
SetInformationJobObject(hjob, JobObjectBasicUIRestrictions, &jobuir,
sizeof(jobuir));
// Spawn the process that is to be in the job.
// Note: You must first spawn the process and then place the process in
// the job. This means that the process’ thread must be initially
// suspended so that it can’t execute any code outside of the job's
// restrictions.
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
BOOL bResult =
CreateProcess(
NULL, (char *)"file.test.exe", NULL, NULL, FALSE,
CREATE_SUSPENDED | CREATE_NEW_CONSOLE | CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &si, &pi);
cerr<<bResult<<endl;
// Place the process in the job.
// Note: If this process spawns any children, the children are
// automatically part of the same job.
bResult = AssignProcessToJobObject(hjob, pi.hProcess);
cerr<<bResult<<endl;
cerr<<GetLastError()<<endl;
// Now we can allow the child process' thread to execute code.
ResumeThread(pi.hThread);
CloseHandle(pi.hThread);
// Wait for the process to terminate or
// for all the job's allotted CPU time to be used.
HANDLE h[2];
h[0] = pi.hProcess;
h[1] = hjob;
DWORD dw = WaitForMultipleObjects(2, h, FALSE, INFINITE);
switch (dw - WAIT_OBJECT_0)
{
case 0:
// The process has terminated...
break;
case 1:
// All of the job's allotted CPU time was used...
break;
}
LARGE_INTEGER CreationTime;
LARGE_INTEGER ExitTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime; GetProcessTimes(pi.hProcess, (LPFILETIME)&CreationTime, (LPFILETIME)&ExitTime,
(LPFILETIME)&KernelTime, (LPFILETIME)&UserTime);
printf("Kernel = %u | User = %u\n", KernelTime.QuadPart / 100000, UserTime.QuadPart / 100000);
//MessageBox(GetActiveWindow(), szInfo, "Restricted Process times",
// MB_ICONINFORMATION | MB_OK);
// Clean up properly.
CloseHandle(pi.hProcess);
CloseHandle(hjob);
}
int main(void)
{
StartRestrictedProcess();
return 0;
}
另外求解如何限制job中进程不允许读写文件、关闭计算机(也就是问JOBOBJECT_SECURITY_LIMIT_INFORMATION 的各个参数和作用)
----------------------------
这个Job限制不了。得Hook
-----------------------------------------------
该结构有点诡异,因为它包含了与限制作业无关的成员。首先,IoInfo是保留成员,不应以任何方式访问它。此外,PeakProcessMemoryUsed和PeakJobMemoryUsed成员是只读的,分别告诉我们已调拨给作业中的任何一个进程所需的存储空间的峰值,以及已调拨给作业中全部进程所需的存储空间的峰值。其余两个成员ProcessMemoryLimit和JobMemoryLimit分别限制着作业中的任何一个进程或全部进程所使用的己调拨的存储空间。为了设置这样的限制,需要在LimitFlags成员中分别指定JOB_OBJECT_LIMIT_JOB_MEMORY和JOB_OBJECT_LIMIT_PROCESS_MEMORY标志。
JOBOBJECT_BASIC_LIMIT_INFORMATION
扩展后的基本限制
JOBOBJECT_EXTENDED_LIMIT_INFORMATION
基本的UI限制
JOBOBJECT_BASIC_UI_RESTRICTIONS
安全限制
JOBOBJECT_SECURITY_LIMIT_INFORMATION
部分代码如下:Imports VijosNT.LocalDbNamespace Executing
Friend Class Executor
Implements IDisposable Private m_SyncRoot As Object
Private m_AvailableSlots As Int32
Private m_Pools As Dictionary(Of EnvironmentTag, EnvironmentPoolBase)
Private m_PendingExecutees As Queue(Of Executee)
Private m_EnableSecurity As Boolean Public Sub New()
Dim Slots As Int32 = Config.ExecutorSlots m_SyncRoot = New Object()
m_AvailableSlots = Slots
m_Pools = New Dictionary(Of EnvironmentTag, EnvironmentPoolBase)()
m_PendingExecutees = New Queue(Of Executee)()
m_EnableSecurity = Config.EnableSecurity Dim TrustedPool As New TrustedEnvironmentPool()
TrustedPool.Executor = Me
m_Pools.Add(EnvironmentTag.Trusted, TrustedPool) If m_EnableSecurity Then
Dim UntrustedPool As New UntrustedEnvironmentPool(GetUntrustedEnvironments())
UntrustedPool.Executor = Me
m_Pools.Add(EnvironmentTag.Untrusted, UntrustedPool)
Else
m_Pools.Add(EnvironmentTag.Untrusted, TrustedPool)
End If
End Sub Private Function GetUntrustedEnvironments() As IEnumerable(Of UntrustedEnvironment)
Dim Result As New List(Of UntrustedEnvironment)
Using Reader As IDataReader = UntrustedEnvironments.GetAll()
While Reader.Read()
Result.Add(New UntrustedEnvironment(Reader("UserName"), Reader("Password")))
End While
End Using
Return Result
End Function Public Function Take() As Boolean
SyncLock m_SyncRoot
If m_AvailableSlots <> 0 Then
m_AvailableSlots -= 1
Return True
Else
Return False
End If
End SyncLock
End Function Public Sub Untake()
SyncLock m_SyncRoot
If m_PendingExecutees.Count <> 0 Then
Dim Executee As Executee = m_PendingExecutees.Dequeue()
m_Pools(Executee.RequiredEnvironment).Queue(Executee)
Else
m_AvailableSlots += 1
End If
End SyncLock
End Sub Public Sub Queue(ByVal Executee As Executee)
If Take() Then
m_Pools(Executee.RequiredEnvironment).Queue(Executee)
Else
SyncLock m_SyncRoot
m_PendingExecutees.Enqueue(Executee)
End SyncLock
End If
End Sub#Region "IDisposable Support"
Private disposedValue As Boolean ' 检测冗余的调用 ' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
For Each Pool As EnvironmentPoolBase In m_Pools.Values
Pool.Dispose()
Next
End If
End If
Me.disposedValue = True
End Sub ' Visual Basic 添加此代码是为了正确实现可处置模式。
Public Sub Dispose() Implements IDisposable.Dispose
' 不要更改此代码。请将清理代码放入上面的 Dispose(ByVal disposing As Boolean)中。
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region End Class
End Namespace完整代码请见http://code.google.com/p/vijosnt-mini/
Inherits KernelObject
Implements IDisposable他说的Job,是自己弄的一个Job跟我们C++核心编程里的Job不是一回事