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核心编程 第七章 线程的调度、优先级和亲缘性(下)

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

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

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

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

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

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

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

  6. Windows核心编程 第25章 未处理异常和C ++异常(下)

    这一节东西比较少,本应该归并在上一节里,但是昨天太晚了.就先把那些东西分为上了.这节里面就一个问题,C++异常与结构性异常的对比(try和__try的区别): C++异常与结构性异常的对比 S E H ...

  7. Windows核心编程 第27章 硬件输入模型和局部输入状态

    第27章 硬件输入模型和局部输入状态 这章说的是按键和鼠标事件是如何进入系统并发送给适当的窗口过程的.微软设计输入模型的一个主要目标就是为了保证一个线程的动作不要对其他线程的动作产生不好的影响. 27 ...

  8. Windows核心编程 第三章 内核对象

    第3章内核对象 在介绍Windows API的时候,首先要讲述内核对象以及它们的句柄.本章将要介绍一些比较抽象的概念,在此并不讨论某个特定内核对象的特性,相反只是介绍适用于所有内核对象的特性. 首先介 ...

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

    第1 7章 内存映射文件 对文件进行操作几乎是所有应用程序都必须进行的,并且这常常是人们争论的一个问题.应用程序究竟是应该打开文件,读取文件并关闭文件,还是打开文件,然后使用一种缓冲算法,从文件的各个 ...

最新文章

  1. 2020年Yann Lecun深度学习笔记(下)
  2. CCS MAP文件说明
  3. Effective C++ --2 构造/析构/赋值运算
  4. 关于系统用户数,并发用户数,在线用户数,吞吐量
  5. Ubuntu 建立tftp服务器
  6. koa --- [MVC实现之四]Router、Controller、Service的实现
  7. 使用定时器判断确保某个标签有值才执行方法, 控制js代码执行先后顺序
  8. 剑指offer——面试题29:数组中出现次数超过一半的数字
  9. 《JAVA与模式》— 原型模式
  10. 超标量处理器设计 姚永斌 第2章 Cache 摘录
  11. numpy库的下载与应用
  12. 推荐10个免费的html,10个免费的HTML在线编辑工具
  13. Linux之CentOS7.5安装及克隆
  14. 用QQ邮箱接收网易163企业邮箱的邮件
  15. Android Camera2 Opengles2.0 实时滤镜(冷暖色/放大镜/模糊/美颜)
  16. 世界足坛十大球队球星全力出击
  17. java 连接PLC 问题总结 Windows machine for DCOM access, so as to avoid such exceptions.  [0x00000005]
  18. 04_turtle画奥运五环
  19. 快速保存网页中所有图片的方法
  20. PHP高级面试题(三)

热门文章

  1. GIF Movie Gear V4.2.3 破解版
  2. “男儿有泪不轻弹”和“活着”
  3. 模板实参推导 xx_cast的实现
  4. CSS的单位及css3的calc()及line-height百分比
  5. 网站如何接入支付宝(转)
  6. DevExpress右键菜单使用 zt
  7. Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 8
  8. Ollydbg 常用快捷键
  9. 如何让SQLServer的 itemNum 字段 按照数字大小顺序排序
  10. .net core mysql CodeFirst