作业 (电脑)
在计算机科学中,作业(英语:job)和任务(英语:task,又译为工作)是在存储器中的一组程序指令。它包括了一段虚拟寻址空间标签页,与操作系统资源,提供线程运行的空间。有时候,它与行程被认为是同义的;但也有人认为,在即时系统(real-time)中运行的行程才被称为作业。
Windows作业对象
Windows 2000操作系统开始,job是一组进程的集合,用于限制其使用的资源、性能信息统计维护、自动关闭子进程等。允许将进程组合在一起并创建一个进程的"容器"来限制进程能够做什么。无法将当前进程或它的任何子进程从作业中去除,这个安全特性可以确保进程无法摆脱对它施加的限制。Win32关于作业的API:
- CreateJobObject:创建作业内核对象。若该作业已经存在,则返回一个指向该作业的句柄
- OpenJobObject:打开命名的作业内核对象
- CloseHandle:关闭一个作业内核对象句柄(不会自动终止作业中的进程)
- IsProcessInJob:验证某一个进程是否存在于作业中
- AssignProcessToJobObject:增加一个进程句柄到一个作业内核对象
- TerminateJobObject:终止一个作业的所有进程
- SetInformationJobObject:给job设置资源限制。作业句柄参数不能传递NULL值,以防止进程删除施加于自己身上的限制
- QueryJobInformationObject:查询job资源限制。进程可以调用它获得其所属作业的相关信息(作业句柄参数传递NULL值),使进程能看到自己被施加了哪些限制。
使用CreateProcess创建的子进程默认属于父进程所在的job,除非CreateProcess函数的dwCreationFlags参数设置了CREATE_BREAKAWAY_FROM_JOB标志。这种情况下,不能用AssignProcessToJobObject函数把子进程关联入job。
作业的所有进程都终止,则作业对象被触发(signaled)。
示例
#include <windows.h>
int main()
{
HANDLE hJob = CreateJobObject(0, 0);
if (hJob)
{
//JOBOBJECT_EXTENDED_LIMIT_INFORMATION jeli;
//memset(&jeli, 0, sizeof(jeli));
//jeli.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
//Place some restrictions on processes in the job.
JOBOBJECT_BASIC_LIMIT_INFORMATION jobli = { 0 };
jobli.PriorityClass = IDLE_PRIORITY_CLASS;//The process always runs in the idle priority class.
jobli.PerJobUserTimeLimit.QuadPart = 10000000; //The job cannot use more than 1 second of CPU time. 100-ns pricision
jobli.LimitFlags = JOB_OBJECT_LIMIT_PRIORITY_CLASS | JOB_OBJECT_LIMIT_JOB_TIME;
if (SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &jobli, sizeof(jobli)))
{
if (AssignProcessToJobObject(hJob, GetCurrentProcess()))
{
WinExec("notepad.exe", SW_SHOW);
//I assume that there will never be more than 10 processes in this job.
#define MAX_PROCESS_IDS 10
//Calculate the number of bytes needed for structure & process IDs.
DWORD Cb = sizeof(JOBOBJECT_BASIC_PROCESS_ID_LIST) +
(MAX_PROCESS_IDS - 1) * sizeof(DWORD);
//Allocate the block of memory.
PJOBOBJECT_BASIC_PROCESS_ID_LIST pjobpil = PJOBOBJECT_BASIC_PROCESS_ID_LIST)_alloca(Cb);
//Tell the function the maximum number of processes that we allocated space for.
pjobpil->NumberOfAssignedProcesses = MAX_PROCESS_IDS;
//Request the current set of process IDs.
BOOL bRes = QueryInformationJobObject(hJob, JobObjectBasicProcessIdList,
pjobpil, Cb, &Cb);
//Enumerate the process IDs.
for (int x = 0; x < pjobpil->NumberOfProcessIdsInList; x++)
{
wchar_t ExeName[1024];
DWORD len = 1024;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pjobpil->ProcessIdList[x]);
BOOL Res = QueryFullProcessImageName(
hProcess, //_In_ HANDLE hProcess,
NULL, //_In_ DWORD dwFlags,
ExeName, //_Out_ LPTSTR lpExeName,
&len //_Inout_ PDWORD lpdwSize
);
DWORD dwLastError =GetLastError();
}
}
}
CloseHandle(hJob);
}
return 0;
}