现在的位置: 首页 > 综合 > 正文

《WINDOWS核心编程》读书笔记–第5章:作业

2013年05月30日 ⁄ 综合 ⁄ 共 2320字 ⁄ 字号 评论关闭

作业能将一组进程当作单个实体来处理,并能限制进程所能进行的操作。包含单个进程的作业也是有用的,可以为进程加上通常情况下不能加的限制。只能在Win2000以上的操作系统中使用作业对象。
创建进程使用下面的函数:
HANDLE CreateJobObject(PSECURITY_ATTRIBUTES psa, PCTSTR pszName);
可以用下面的函数访问一个已经存在的命名作业对象:
HANDLE OpenJobObject(DWORD dwDesiredAccess, BOOL bInheritHandle, PCTSTR pszName);
当不需要访问一个作业对象时,要用CloseHandle来关闭它的句柄。
可以给一个作业上加上不同的限制:
(1)基本和扩展基本限制,用于防止作业中的进程垄断系统的资源;
(2)基本UI限制,用于防止作业中的进程改变用户界面;
(3)安全限制,用于防止作业中的进程访问文件、注册表子关键字等保密资源。
用下面的函数:
BOOL SetInformationJobObject(
HANDLE hJob,
JOBOBJECTINFOCLASS JobObjectInformationClass,
PVOID pJobObjectInformation,
DWORD cbJobObjectInformationLength
);
当为第二个参数传递JobObjectBasicLimitInformation时,第三个参数使用JOBOBJECT_BASIC_LIMIT_INFORMATION结构,在这个结构中LimitFlags成员指定对作业进行哪些限制,其余的成员可以用来限制每个进程或作业可以使用多少CPU时间、进程的优先级类、作业中的线程相对 时段差等。其中线程的相对时段差,是0-9的10个数值,默认是5,较大的值的作业可以在相同的优先级下获得更多的CPU时间。如果LimitFlags指定了JOB_OBJECT_DIE_ON_UNHANDLED_EXCEPTION,可以在进程出现错误时不显示“未处理的异常情况”对话框而直接退出,这对作为服务程序和面向批处理的作业很有用;

如果为参数2指定JobObjectExtendedLimitInformation,参数3使用JOBOBJECT_EXTENDED_INFORMATION,它在其中包含了一个JOBOBJECT_BASIC_LIMIT_INFORMATION结构,其余的成员用来记录、设置作业或其中的每个进程的内存最大值,它需要设置基本限制结构中的LimitFlags;

基本界面限制JOBOBJECT_BASIC_UI_LIMIT_INFORMATION只有一个成员用来存放一些标志,限制作业中的进程访问剪贴板、关闭Windows、操作桌面、改变系统参数和显示等,还能不让进程访问外面的作业中的用户对象,但是是单向的。可以在作业外调用函数UserHandleGrantAccess,允许作业中的进程访问作业外的一个用户对象(如窗口)。

用函数QueryInformationJobObject可以查询限制信息,另外这个函数还可以用JOBOBJECT_BASIC_ACCOUNTING_INFORMATION结构查询运行了多少时间,总共有多少个进程,多少个活动的进程等;用JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION查询读完次数等信息,用函数GetProcessIoCounters可以查询不在作业中的进程的读写信息;也可以用JOBOBJECT_BASIC_PROCESS_ID_LIST枚举作业中的所有进程的ID。

下面的函数:
BOOL AssignProcessToJobObject(HANDLE hJob, HANDLE hProcess);
可以把一个进程加入到一个作业中去,前提是这个进程不能属于其他的作业,却成功加入后将一直属于这个作业。作业中进程生成的子进程默认的也是该作业中的成员。但是有两种方法可以破除这个规定:
(1)JOBOBJECT_BASIC_LIMIT_INFORMATION的LimitFlags指定了JOB_OBJECT_BREAKAWAY_OK,作业中的进程使用CREATE_BREAKAWAY_FROM_JOB标志创建的子进程就不在作业中。
(2)JOBOBJECT_BASIC_LIMIT_INFORMATION的LimitFlags指定了JOB_OBJECT_SLIENT_BREAKAWAY_OK,作业中创建的子进程自动就不是作业中的一员。

函数 BOOL TerminateJobObject(HANDLE hJob, UINT uExitCode)可以停止作业中所有进程的运行。

当一个作业 中的进程结束时,可以用WaitForSingleObject函数支发现。而作业结束时,作业对象并不是通知态。若想获得更高级的信息可以使用I/O完成端口对象,传递给SetInformationJobObject一个JOBOBJECT_ASSOCIATE_COMPLETION_PORT将作业和该对象关联起来。线程通过GetQueuedCompletionStatus函数来监控I/O完成端口。
另外,默认的当分配给作业的CPU时间到期时,作业中的所有进程都停止运行。如果将JOBOBJECT_END_OF_JOB_TIME_INFORMATION结构的EndOfJobTimeAction成员赋成JOB_OBJECT_POST_AT_END_OF_JOB,通过调用SetInformationJobObject,在到期时只是通知时间到了。 

抱歉!评论已关闭.