C 当时间流逝时,真正杀死当前进程
我有一个用C编写的Win32控制台程序,在经过一定时间后需要终止,即使它仍然很忙。目前我正在这样做:C 当时间流逝时,真正杀死当前进程,c,windows,winapi,C,Windows,Winapi,我有一个用C编写的Win32控制台程序,在经过一定时间后需要终止,即使它仍然很忙。目前我正在这样做: static VOID CALLBACK timeout(PVOID a, BOOLEAN b) { ExitProcess(0); } 当达到时间限制时,如果程序在计算上很忙,那么这种方法可以很好地工作。例如,当我在main中放置一个无限循环时,它很容易通过测试用例。然而,有一种情况是它不起作用,程序只是无限期地挂起。这种情况与被父进程调用有关,我不知道到底发生了什么,我问了另外一个问题。
static VOID CALLBACK timeout(PVOID a, BOOLEAN b) { ExitProcess(0); }
当达到时间限制时,如果程序在计算上很忙,那么这种方法可以很好地工作。例如,当我在main
中放置一个无限循环时,它很容易通过测试用例。然而,有一种情况是它不起作用,程序只是无限期地挂起。这种情况与被父进程调用有关,我不知道到底发生了什么,我问了另外一个问题。我的问题是:
有没有一种方法可以告诉Windows在一定的秒数后,不管发生什么情况,都要真的杀死当前进程
更新:刚刚试验过,WT_EXECUTEINTIMERTHREAD
似乎解决了这个问题。这就留下了几个问题:
在
SleepEx
之后,通过调用fromNTDLL.DLL
进行后续操作。这将确保进程在调用ExitProcess
之前执行预先检查时终止,然后再调用ZwTerminateProcess/Thread
。在这里,你可以称之为自己,并确保终止!通过将GetCurrentProcess()
传递给参数,可以为ZwTerminateProcess
填充HANDLE
参数。或者,您可以通过ZwQuerySystemInformation->ZwOpenProcess
扫描进程列表,或者创建快照(CreateToolhelp32Snapshot
…从我的头顶上),获得远程进程的句柄然后是Process32First->Next->OpenProcess
-如果您拥有SE\u DEBUG\u特权,并且当前进程与另一个进程从相同的完整性级别执行,那么您可以使用ZwTerminateProcess
终止远程进程 退出进程实际上应该终止当前进程。恐怕您需要告诉我们更多有关这种情况的信息,这种情况与您不知道发生了什么的父进程调用有关。也许可以提供一个单独问题的链接?@MikeNakis关于父进程发生了什么的问题是-如果ExitProcess可以完成任务,那一定意味着我的超时函数没有被调用;有没有一种方法可以保证无论发生什么情况,超时函数都会被调用?只需在退出进程(0)
之前生成一个单独的线程,该线程执行睡眠(time\u limit*1000)
。在您当前的设置中,我无法确定,但可能是您设置的计时器依赖于与标准输入/标准输出的一些成功交互,而这不起作用,因为它们被一个现在已死亡的父进程重定向,因此计时器也不起作用。您可以通过在ExitProcess(0)
之前编写一个长条目来验证这一点。我打赌你永远不会看到日志条目。我敢打赌,如果你使用分离线程的方法,你会看到它。听起来你是在重新发明。试着使用TerminateProcess(GetCurrentProcess(),1)
而不是ExitProcess
:“如果在用户模式下调用此函数,则应使用名称“NtTerminateProcess”而不是“zwtterminateprocess”。“无需使用这两个名称。”。普通的旧TerminateProcess应该可以很好地工作。@IIInspectable NtTerminateProcess指向ZwTerminateProcess,不存在兼容性问题。在我的整个工作过程中,我一直在使用它无数次,从来没有任何问题!如果你需要违反合同,你需要一个很好的理由。“我从来没有任何问题[违反合同]”不是一个很好的理由。@IInspectable MSV不是合同。它只是围绕给定API的文档。你可以从它那里得到建议,但它不像学校;你可以用任何你想用的方式来处理它,而不仅仅是根据教科书上的内容:)
HANDLE timer = 0;
CreateTimerQueueTimer(&timer, 0, timeout, 0, (DWORD)(time_limit * 1000),
0, 0);