创意网站页面/b2b网站大全免费
需求:
软件功能用多进程实现, 由主进程创建若干子进程, 当主进程崩溃时,创建出来的子进程需要能够自动关闭。
方法1:
进程通信,子进程检查心跳包,一段时间没心跳包则退出进程。
缺点:
1.实现起来麻烦。
2.不支持第三方的程序,因为别人并未实现这些心跳机制。
3.依然存在可能程序有BUG, 子进程卡死不退出的现象。
方法2:
通过作业对象(Job Object来实现), 作业对象是Windows系统提供的对加入作业的进程做特定限制的内核对象,可以对作业中的进程组统一做时间片分配,网络,CPU亲缘性设置等。并且可以设置JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
标志,当作业对象释放,回收时(包括主进程崩溃),由操作系统来保证子进程结束。
相关API:
// 创建作业对象
HANDLE CreateJobObjectA([in, optional] LPSECURITY_ATTRIBUTES lpJobAttributes,[in, optional] LPCSTR lpName
);// 把进程加入作业。
BOOL AssignProcessToJobObject([in] HANDLE hJob,[in] HANDLE hProcess
);// 设置作业的限制内容
BOOL SetInformationJobObject([in] HANDLE hJob,[in] JOBOBJECTINFOCLASS JobObjectInformationClass,[in] LPVOID lpJobObjectInformation,[in] DWORD cbJobObjectInformationLength
);// 查询作业的限制内容。
BOOL QueryInformationJobObject([in, optional] HANDLE hJob,[in] JOBOBJECTINFOCLASS JobObjectInformationClass,[out] LPVOID lpJobObjectInformation,[in] DWORD cbJobObjectInformationLength,[out, optional] LPDWORD lpReturnLength
);
实现代码:
//========================= 创建进程 ============================//
char Proc_Path[] = "notepad.exe"; // 进程路径STARTUPINFOA startup_info;
memset(&startup_info, 0x0, sizeof(startup_info));
startup_info.cb = sizeof(startup_info);
startup_info.wShowWindow = SW_SHOW;PROCESS_INFORMATION proc_info;
memset(&proc_info, 0x0, sizeof(proc_info));
BOOL create_ok = CreateProcessA(NULL, Proc_Path, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &startup_info, &proc_info
);
//------------------------------------------------------------------------//HANDLE job_handle = CreateJobObject(NULL, NULL); // 创建Job对象
BOOL add_job_ok = AssignProcessToJobObject(job_handle, proc_info.hProcess); // 把进程加入Job//=========== 设置Job对象回收, 所有相关进程自动退出 ============//
JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info;
memset(&limit_info, 0x0, sizeof(limit_info));
limit_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; // job句柄回收时,所有加入job的进程都会强制结束。
BOOL set_auto_kill_ok = SetInformationJobObject(job_handle, JobObjectExtendedLimitInformation, &limit_info, sizeof(limit_info)
);
//-----------------------------------------------------------------///*释放job对象, 调用后,所有相关进程都会退出。假如程序崩溃没调用释放, 由系统回收,也能达到结束所有相关进程的效果。 在多进程系统中,这个特性必用,应对出现僵尸子进程的现象。
*/
CloseHandle(job_handle);