Windows实现主进程退出,子进程自动关闭功能

12 篇文章 0 订阅

需求:

软件功能用多进程实现, 由主进程创建若干子进程, 当主进程崩溃时,创建出来的子进程需要能够自动关闭。

方法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); 

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值