读书人

【Windows核心编程学习札记】作业

发布时间: 2012-11-23 00:03:43 作者: rapoo

【Windows核心编程学习笔记】作业

一、什么是作业

我们经常需要将一组进程当做一个单独的组来处理。Windows提供了一个作业(job)内核对象,允许我们将进程组合在一起并创建一个“沙箱”来限制进程能够做什么。最好将作业对象想象成一个进程容器。创建只包含一个进程的作业同样很有用,这样可以对进程施加平时不能施加的限制。


二、对作业中的进程施加限制

可以向作业应用以下几种类型的限制:

基本限额和扩展基本限额,用于放置作业中的进程独占系统资源。基本的UI限制,用于放置作业内的进程更改用户界面。安全限额,用于防止作业内的进程访问安全资源(文件、注册表子项等)。

要为作业中的进程创建一个真正安全的沙箱,对UI句柄进行限制是十分强大的一个能力。不过,有时仍然需要让作业内部的进程同作业外部的一个进程通信。一个简单的办法是使用窗口消息,但是,如果作业中的进程不能访问UI句柄,那么作业额内部的进程就不能向作业外部的进程创建一个窗口发送或发布窗口消息。但是,可以用另外一个函数来解决问题:

BOOL WINAPI TerminateJobObject(  _In_  HANDLE hJob,  _In_  UINT uExitCode);
这类似于为作业内的每一个进程调用TerminateProcess,将所有的推出代码设置为uExitCode。


五、作业通知

有时候,我们想知道作业中的所有进程何时终止只需,或者所有已分配的CPU时间是否已经到期,还想知道作业内部何时生成了一个新的进程,或者作业中的进程何时终止执行?这个时候就需要用到作业通知。

如果只是需要知道已分配的CPU时间是否已经到期,比较简单。作业中的进程如果尚未用完已分配的CPU时间,作业对象处于未出发的状态。一旦用完,Windows会强行杀死作业中的所有进程并出发作业对象。通过调用函数WaitForSingleObject可以轻松捕捉到这个事件。

注意一个误区是:认为作业对象中没有任何进程运行的时候,作业就处于触发状态。虽然进程和线程会在停止运行的时候触发。但是,Windows选择在已分配的CPU事件到期的时候将作业的状态置为触发的。因为在许多作业中,都存在一个父进程一直在运行,直至其所有子进程全部结束。所以,我们只能等待父进程的句柄得知整个作业事件何时结束。

要想获得一些更高级的通知(比如进程创建/终止),必须创建一个I/O端口(Completion port)内核对象,并将我们的作业对象与完成端口相关联。然后,我们必须有一个或者多个线程等待作业通知到达完成端口。以便对他们进行处理。

读书人网 >编程

热点推荐