5.4 查询作业统计信息

前面已经介绍了如何使用 Q u e r y I n f o r m a t i o n J o b O b j e c t函数来获取对作业的当前限制信息。也可以使用它来获取关于作业的统计信息。例如,若要获取基本的统计信息,可以调用Q
u e r y I n f o r m a t i o n J o b O b j e c t,为第二个参数传递J o b O b j e c t B a s i c A c c o u n t i n g I n f o r m a t i o n ,并传递

J O B O B J E C T _ B A S I C _ A C C O U N T I N G _ I N F O R M AT I O N结构的地址:

表5 - 5简要描述了它的各个成员。

除了查询这些基本统计信息外,可以进行一次函数调用,以同时查询基本统计信息和 I / O统计信息。为此,必须为第二个参数传递
J o b O b j e c t B a s i c A n d I o A c c o u n t i n g I n f o r m a t i o n ,并传递J O B O B J E C T _ B A S I C _ A N D _ I O _ A C C O U
N T I N G _ I N F O R M AT I O N结构的地址:

如你所见,这个结构只返回一个J O B O B J E C T _ B A S I C _ A C C O U N T I N G _ I N F O R M AT I O N结构和I O _ C O U N T E R S结构:

该结构告诉你作业中的进程已经执行的读、写和非读 /写操作的数量(以及在这些操作期间传送的字节数) 。另外,可以使用下面这个新的
G e t P r o c e s s I o C o u n t e r s函数,以便获取不是这些作业中的进程的这些信息:

也可以随时调用Q u e r y I n f o r m a t i o n J o b O b j e c t函数,以便获取当前在作业中运行的进程的一组进程I D。若要进行这项操作,首先必须确定你想在作业中看到多少进程,然后必须分配足够的内存块,来放置这些进程I
D的数组,并指定J O B O B J E C T _ B A S I C _ P R O C E S S _ I D _ L I S T结构的大小:

因此,若要获得当前作业中的一组进程I D,必须执行类似下面的代码:

这就是你使用这些函数的所有实现方法,不过操作系统实际上保存了更多的关于作业的信息。它是使用性能计数器来进行这项操作的。可以使用 Performance Data Helper函数库(P D H . d l l)中的函数来检索这些信息。也可以使用
Microsoft Management Console(MMC)的Performance
Monitor Snap-In来查看作业信息。图5 - 2显示了系统中的作业对象可以使用的一些计数器。图5
- 3显示了可以使用的一些作业对象的明细计数器。也可以看到
J e ff的作业里有4个进程,即c
a l c、c m d、n o t e p a d和w
o r k p a d。

注意,当调用C r e a t e J o b O b j e c t函数时,只能为已经赋予名字的作业获取性能计数器信息。由于这个原因,即使不打算按名字来共享跨越进程的作业对象,也应该创建带有名字的这些对象。

5.5 作业通知信息

现在,已经知道了关于作业对象的基本知识,剩下要介绍的内容是关于通知的问题。例如,是否想知道作业中的所有进程何时终止运行或者分配的全部 C P U时间是否已经到期呢?也许想知道作业中何时生成新进程或者作业中的进程何时终止运行。如果不关心这些通知信息(而且许多应用程序也不关心这些信息) ,作业的操作非常容易。如果关心这些事件,那么还有一些工作要做。

如果关心的是分配的所有C P U时间是否已经到期, 那么可以非常容易地得到这个通知信息。当作业中的进程尚未用完分配的C P U时间时,作业对象就得不到通知。一旦分配的所有
C P U时间已经用完,
Wi n d o w s就强制撤消作业中的所有进程,并将情况通知作业对象。通过调用Wa i t F o r S i n g l e O b j e c t (或类似的函数),可以很容易跟踪这个事件。有时,可以在晚些时候调用

S e t I n f o r m a t i o n J o b O b j e c t函数,使作业对象恢复未通知状态,并为作业赋予更多的C P U时间。

当开始对作业进行操作时,我觉得当作业中没有任何进程运行时,应该将这个事件通知作业对象。毕竟当进程和线程停止运行时,进程和线程对象就会得到通知。因此,当作业停止运行时它也应该得到通知。这样,就能够很容易确定作业何时结束运行。但是, M i c r o s o f t选择在分配的C
P U时间到期时才向作业发出通知,因为这显示了一个错误条件。由于许多作业启动时有一个父进程始终处于工作状态,直到它的所有子进程运行结束,因此只需要在父进程的句柄上等待,就可以了解整个作业何时运行结束。 S t a r t R e s t r i c
t e d P r o c e s s函数用于显示分配给作业的C P U时间何时到期,或者作业中的进程何时终止运行。

前面介绍了如何获得某些简单的通知信息,但是尚未说明如何获得更高级的通知信息,如进程创建/终止运行等。如果想要得到这些通知信息,必须将更多的基础结构放入应用程序。特别是,必须创建一个
I / O完成端口内核对象,并将作业对象或多个作业对象与完成端口关联起来。然后,必须让一个或多个线程在完成端口上等待作业通知的到来,这样它们才能得到处理。

一旦创建了I / O完成端口,通过调用S e t I n f o r m a t i o n J o b O b j e c t函数,就可以将作业与该端口关联起来,如下面的代码所示:

当上面的代码运行时,系统将监视该作业的运行,当事件发生时,它将事件送往 I / O完成端口(顺便说一下,可以调用Q u e r y I n f o r m a t i o m J o b O b j e c t函数来检索完成关键字和完成端口句柄。但是,这样做的机会很少)
。线程通过调用G e t Q u e u e d C o m p l e t i o n S t a t u s函数来监控I / O完成端口:

当该函数返回一个作业事件通知时,* p C o m p l e t i o n K e y包含了调用S e t I n f o r m a t i o n J o b O b j e c t时设置的完成关键字值,用于将作业与完成端口关联起来。它使你能够知道哪个作业存在一个事件。*
p N u m B y t e s Tr a n s f e r r e d中的值用于指明发生了哪个事件。根据事件(见表5 - 6) ,*pOverlapped

的值将指明一个进程I D。

最后要说明的一点是,按照默认设置,作业对象是这样配置的:当分配给作业的 C P U时间已经到期时,作业的所有进程均自动停止运行,而
J O B _ O B J E C T _ M S G _ E N D _ O F _ J O B _ T I M E通知尚未发送。如果想要防止作业对象撤消进程而只是通知你时间已经超过,必须执行下面这样的代码:

为作业设定结束时间而使用的另一个值是J O B _ O B J E C T _ T E R M I N AT E _ AT _ E N D _ O F _ J O B,这是作业创建时的默认值。

Windows核心编程 第五章 作业(下)的更多相关文章

  1. Windows核心编程 第五章 作业(上)

    第5章 作 业 通常,必须将一组进程当作单个实体来处理.例如,当让 Microsoft Developer Studio为你创建一个应用程序项目时,它会生成 C l . e x e,C l . e x ...

  2. windows核心编程---第五章 线程的基础

    与前面介绍的进程一样,线程也有两部分组成.一个是线程内核对象.它是一个数据结构,操作系统用它来管理线程以及用它来存储线程的一些统计信息.另一个是线程栈,用于维护线程执行时所需的所有函数参数和局部变量. ...

  3. windows核心编程 第5章job lab示例程序 解决小技巧

    看到windows核心编程 第5章的最后一节,发现job lab例子程序不能在我的系统(win8下)正常运行,总是提示“进程在一个作业里”         用process explorer程序查看 ...

  4. windows核心编程 第8章201页旋转锁的代码在新版Visual Studio运行问题

    // 全局变量,用于指示共享的资源是否在使用 BOOL g_fResourceInUse = FALSE; void Func1() { //等待访问资源 while(InterlockedExcha ...

  5. Windows核心编程 第七章 线程的调度、优先级和亲缘性(下)

    7.6 运用结构环境 现在应该懂得环境结构在线程调度中所起的重要作用了.环境结构使得系统能够记住线程的状态,这样,当下次线程拥有可以运行的C P U时,它就能够找到它上次中断运行的地方. 知道这样低层 ...

  6. windows核心编程---第七章 用户模式下的线程同步

    用户模式下的线程同步 系统中的线程必须访问系统资源,如堆.串口.文件.窗口以及其他资源.如果一个线程独占了对某个资源的访问,其他线程就无法完成工作.我们也必须限制线程在任何时刻都能访问任何资源.比如在 ...

  7. Windows核心编程 第十七章 -内存映射文件(下)

    17.3 使用内存映射文件 若要使用内存映射文件,必须执行下列操作步骤: 1) 创建或打开一个文件内核对象,该对象用于标识磁盘上你想用作内存映射文件的文件. 2) 创建一个文件映射内核对象,告诉系统该 ...

  8. Windows核心编程 第六章 线程基础知识 (下)

    6.6 线程的一些性质 到现在为止,讲述了如何实现线程函数和如何让系统创建线程以便执行该函数.本节将要介绍系统如何使这些操作获得成功. 图6 - 1显示了系统在创建线程和对线程进行初始化时必须做些什么 ...

  9. Windows核心编程 第四章 进程(下)

    4.3 终止进程的运行 若要终止进程的运行,可以使用下面四种方法: • 主线程的进入点函数返回(最好使用这个方法) . • 进程中的一个线程调用E x i t P r o c e s s函数(应该避免 ...

随机推荐

  1. python学习总结篇(2)——函数

    如其他语言一样,除了基本知识外,另外一个重要的板块就是函数了,python中也有函数. 在python中,函数的定义方式为: def   函数名( ): 下面通过几个简单的例子,看看python中的函 ...

  2. ZooKeeper 的选举机制,你了解多少?

    本文作者:HelloGitHub-老荀 Hi,这里是 HelloGitHub 推出的 HelloZooKeeper 系列,免费开源.有趣.入门级的 ZooKeeper 教程,面向有编程基础的新手. 项 ...

  3. 一文弄懂js的执行上下文与执行上下文栈

    目录 执行上下文与执行上下文栈 变量提升与函数提升 变量提升 函数提升 变量提升与函数提升的优先级 变量提升的一道题目引出var关键字与let关键字各自的特性 执行上下文 全局执行上下文 函数(局部) ...

  4. solr简明教程

    文章目录 安装 启动 创建core 配置core索引MySQL数据 3.2.1 3.2.2 3.2.3 测试定时更新 五.配置中文分词 SolrJ 操作索引的增.删.查 七.通过SolrJ对MySQL ...

  5. 从yield到yield from再到python协程

    yield 关键字 def fib(): a,b = 0,1 while 1: yield b a,b = b,a+b yield是在:PEP 255 -- Simple Generators 这个p ...

  6. 一个名叫Sentinel-Rules-SDK的组件,使得Sentinel的流控&熔断规则的配置更加方便

    原文链接:一个名叫Sentinel-Rules-SDK的组件,使得Sentinel的流控&熔断规则的配置更加方便 1 Sentinel 是什么? 随着微服务的流行,服务和服务之间的稳定性变得越 ...

  7. HTML标签解读

    因为最近在学习爬虫,那么在爬取网页内容时,就要求我们能够简单的看懂这个网页的基本结构,才能更好的去爬取我们所需要的内容. 这篇随笔也只是简单的说明了一些标签的含义. 标签关系 包含关系 eg:< ...

  8. Java字符串==和equals的区别

    首先我们来了解一下String类,Java的字符串是一旦被赋值之后无法更改的(这里的无法更改是指不能将字符串中单个或一段字符重新赋值),这也是Java虚拟机为了减少内存开销,避免字符串的重复创建设立的 ...

  9. Vue中的Xss构造

    首发tools:https://www.t00ls.net/thread-59512-1-1.html 存储型XSS 最近做测试的时候碰到了一个前端页面使用了Vue框架的项目 在测试XSS漏洞的过程中 ...

  10. Elasticsearch 分页查询

    目录 前言 from + size search after scroll api 总结 参考资料 前言 我们在实际工作中,有很多分页的需求,商品分页.订单分页等,在MySQL中我们可以使用limit ...