5.6 作业对象事件和完成端口
(1)将作业对象与完成端口对象关联起来
JOBOBJECT_ASSOCIATE_COMPLETION_PORT joacp;
joacp.CompletionKey = hJob1; //可用来标识作业对象任意唯一值,这里取其句柄
joacp.CompletionPort = hIOCP; //完成端口的句柄
SetInformationJobObject(hJob,JobObjectAssociateCompletionPortInformation,
&joacp,sizeof(joacp));
(2)创建线程,将完成端口对象作为参数传入线程函数。并GetQueuedCompletionStatus来等待作业对象的通知事件。
参数 |
描述 |
hIOCP |
要获取事件的完成端口对象的句柄 |
pNumBytesTransferred |
等待的事件ID 【与作业对象有关的事件】 ①JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT:作业对象中活动进程数达到上限时通知 ②JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO:作业对象中当前没有活动进程时通知 ③JOB_OBJECT_MSG_END_OF_JOB_TIME:作业对象耗尽指定的时间片时通知。但其中的进程不会自动终止。可以设置一个新的时间限额以允许继续,或调用TerminateJobObject来终止进程。 ④JOB_OBJECT_MSG_JOB_MEMORY_LIMIT:作业对象耗尽指定的内存时通知,同时给出进程ID 【与进程有关的事件】 ①JOB_OBJECT_MSG_NEW_PROCESS:新进程加入作业对象时通知,并给出进程ID。 ②JOB_OBJECT_MSG_EXIT_PROCESS:进程正常退出时通知,并给出进程ID。 ③JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS:进程异常退出时通知,并给出进程ID ④JOB_OBJECT_MSG_END_OF_PROCESS_TIME:进程耗尽时间片时通知,进程将终止,并给出进程ID ⑤JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT:进程消耗内存数量达到上限时通知,同时给出进程ID。 |
pCompletionKey |
指定触发这个事件的作业对象的句柄(可以将一个完成端口对象与多个作业对象进行绑定) |
pOverlapped |
在作业事件中,该值表示哪个进程ID发生的事件。 |
dwMilliseconds |
用于指定调用者等待完成端口的时间 |
注意:
①作业对象的状态变为己触发是在分配作业的时间到期时,而不是所有进程都结束时。
②默认下,当作业时间到期时,它的所有进程都会自动终止,所以也就不会投递JOB_OBJECT_MSG_END_OF_JOB_TIME。如果只想发送该通知给应用程序,而让应用程序自行来杀死进程,可以做如下设置:
//创建结构体,并将JOb结束时要采取的措施填入该结构体
JOBOBJECT_END_OF_JOB_TIME_INFORMATION joeojti;
joeojti.EndOfJobTimeAction = JOB_OBJECT_POST_AT_END_OF_JOB; //投递通知,而不是“杀死”进程。创建作业时,默认值为JOB_OBJECT_TERMINATE_AT_END_OF_JOB;
//告诉作业对象当作业时间到期时,要采取的措施
SetInformationJobObject(hJob,JobObjectEndOfJobTimeInformation,
&joeojti,sizeof(joeojti));
【JobIO】利用完成端口实现进程管理