作業 (電腦)
在電腦科學中,作業(英語: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;
}