作業 (電腦)

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

參見