windows 核心编程 - windows作业限制设置

演示作业限制设置

演示作业限制设置


演示作业限制设置


/*
演示作业限制设置
*/

#include"..\\CommonFiles\\CmnHdr.h"
#include "resource.h"

#include "Job.h"
#include<tchar.h>
#include<strsafe.h>
#include<windowsx.h>



HWND g_hwnd;				//对话框句柄(被所有的线程访问)
HANDLE g_hIOCP;				//用来接受作业通知完成的端口
HANDLE g_hThreadIOCP;		//完成端口线程句柄
CJob g_job;					//作业对象句柄


//完成端口的CompletionKey 
#define COMPKEY_TERMINATE	((UINT_PTR)0)
#define COMPKEY_STATUS		((UINT_PTR)1)
#define COMPKEY_JOBOBJECT	((UINT_PTR)2)


void GetProcessName(DWORD PID, PTSTR szProcessName, size_t cchSize) {
   
	HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, PID);
	if (hProcess ==NULL)
	{
   
		_tcscpy_s(szProcessName, cchSize, TEXT("???"));
		return;
	}
	//....
	//以上函数调用,可用下列函数来替代,因为下列函数可适用各种情况
	DWORD dwSize = (DWORD)cchSize;
	QueryFullProcessImageName(hProcess, 0, szProcessName, &dwSize);
	CloseHandle(hProcess);
}


DWORD WINAPI JobNotify(PVOID) {
   
	TCHAR sz[3000];
	BOOL fDone = FALSE;
	ULONG_PTR CompKey;//指定出发这个事件的作业对象的句柄
	LPOVERLAPPED po;//进程ID
	DWORD dwBytesXferred;//等待的事件ID

	while (!fDone)
	{
   
		GetQueuedCompletionStatus(g_hIOCP, &dwBytesXferred, 
			&CompKey, &po, INFINITE);
		

		//应用程序关闭,退出线程
		fDone = (CompKey == COMPKEY_TERMINATE);

		//lpClassName为NULL则查找所有标题与第二个参数匹配的窗口
		HWND hwndLB = FindWindow(NULL, TEXT("Job Lab"));
		hwndLB = GetDlgItem(hwndLB, IDC_STATUS);

		if (CompKey == COMPKEY_JOBOBJECT)
		{
   
			_tcscpy_s(sz, _countof(sz), TEXT("--> Notification:"));
			PTSTR psz = sz + _tcslen(sz);
			switch (dwBytesXferred)
			{
   
			 //作业对象中活动进程数量达到上限
			case JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT:
				StringCchPrintf(psz, _countof(sz) - _tcslen(sz),
					TEXT("作业对象中活动进程数已达到上限!"));
				break;

				//作业对象中当前没有活动的进程
			case JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:
				StringCchPrintf(psz, _countof(sz) - _tcslen(sz),
					TEXT("作业对象中当前没有活动进程"));
				break;

				//作业对象耗尽指定的时间片
			case JOB_OBJECT_MSG_END_OF_JOB_TIME: {
   
				StringCchPrintf(psz, _countof(sz) - _tcslen(sz),
					TEXT("作业对象耗尽指定的时间片"));
				}
				break;
				//作业对象耗尽指定的内存
			case JOB_OBJECT_MSG_JOB_MEMORY_LIMIT: {
   
				TCHAR szProcessName[MAX_PATH];
				GetProcessName(PtrToUlong(po), szProcessName, MAX_PATH);//po存在进程ID
				StringCchPrintf(psz, _countof(sz) - _tcslen(sz),
					TEXT("进程 %s(ID=%d)导致作业对象消耗内存到达到上限!"),szProcessName,po);
				}
												break;
												//新进程加入作业对象
			case JOB_OBJECT_MSG_NEW_PROCESS: {
   
				TCHAR szProcessName[MAX_PATH];
				GetProcessName(PtrToUlong(po), szProcessName, MAX_PATH);
				StringCchPrintf(psz, _countof(sz) - _tcslen(sz),
					TEXT("进程 %s(ID=%d)加入作业对象!"), szProcessName, po);

			}
										   break;

										   //进程正常退出
			case JOB_OBJECT_MSG_EXIT_PROCESS: {
   
				TCHAR szProcessName[MAX_PATH];
				DWORD dwExitCode = 0;
				//注意进程退出了。但其内核对象并没有释放,还可以从内核对象中获取推出吗
				HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, PtrToUlong(po));
				if (NULL != hProcess)
				{
   
					GetExitCodeProcess(hProcess, &dwExitCode);
					CloseHandle(hProcess);
				}
				GetProcessName(PtrToUlong(po), szProcessName, MAX_PATH);//po存在进程ID
				StringCchPrintf(psz, _countof(sz) - _tcslen(sz),
					TEXT("进程 %s(ID=%d)正常退出,推出码(%d)!"), szProcessName, po, dwExitCode);
			}
											break;
											

											//进程异常退出
			case JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS: {
   
				TCHAR szProcessName[MAX_PATH];
				DWORD dwExitCode = 0;
				//注意进程退出了。但其内核对象并没有释放,还可以从内核对象中获取推出吗
				HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, PtrToUlong(po));
				if (NULL != hProcess)
				{
   
					GetExitCodeProcess(hProcess, &dwExitCode);
					CloseHandle(hProcess);
				}
				GetProcessName(PtrToUlong(po), szProcessName, MAX_PATH);//po存在进程ID
				StringCchPrintf(psz, _countof(sz) - _tcslen(sz),
					TEXT("进程 %s(ID=%d)异常退出,推出码(%d)!"), szProcessName, po, dwExitCode);
			}
													 break;

													 //进程耗尽时间片
			case JOB_OBJECT_MSG_END_OF_PROCESS_TIME: {
   
				TCHAR szProcessName[MAX_PATH];
				GetProcessName(PtrToUlong(po), szProcessName, MAX_PATH);
				StringCchPrintf(psz, _countof(sz) - _tcslen(sz),
					TEXT("进程%s(ID-%d)耗尽事件片!"), szProcessName, po);
			}
												   break;

												   //进程小号内存数量达到上限
			case JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT: {
   
				TCHAR szProcessName[MAX_PATH];
				GetProcessName(PtrToUlong(po), szProcessName, MAX_PATH);
				StringCchPrintf(psz, _countof(sz) - _tcslen(sz),
					TEXT("进程%s(ID=%d)小号内存达到上限!"), szProcessName, po);
			}
													break;
			default:
				StringCchPrintf(psz, _countof(sz) - _tcslen(sz),
					TEXT("未知通知:%d"), dwBytesXferred);
			}
			ListBox_SetCurSel(hwndLB, ListBox_AddString(hwndLB, sz));
			CompKey = 1;//当作业通知到达时,强迫更新状态
		}

		//更新作业状态
		if (CompKey == COMPKEY_STATUS)
		{
   
			static int s_nStatusCount = 0;
			StringCchPrintf(sz, _countof(sz),
				TEXT("-->状态更新(%u)"), s_nStatusCount++);
			ListBox_SetCurSel(hwndLB, ListBox_AddString(hwndLB, sz));

			//显示作业对象的基本统计信息
			JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION jobai;
			g_job.QueryBasicAccountingInfo(&jobai);

			StringCchPrintf(sz, _countof(sz),
				TEXT(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值