作業 (電腦)

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

參見