在尝试解决之前提到的SO我的问题时,我发现即使没有我的线程,也会出现问题。
我现在拥有的是一个非常简单的单线程代码,可以调用 - NetServerEnum()
。返回时,它调用NetApiBufferFree()
并从main返回,它应该结束进程。
在那一点上,我的线程真的结束了,但是这个过程不会退出,因为有4个线程被打开(不是我):
1 * ntdll.dll!TplsTimerSet+0x7c0
(堆栈位于ntdll.dll!WaitForMultipleObjects
)
(这个是在致电NetServerEnum()
时打开的)
3 * ndll.dll!RtValidateHeap+0x170
(堆栈位于ntdll.dll!ZwWaitWorkViaWorkerFactory+0xa
)
(这些代码在我的代码返回时打开)
更新:
如果我在外部(使用进程资源管理器)杀死运行ntdll.dll!TplsTimerSet + 0x7c0的线程,则在返回main()
之前,程序会正常退出。
我认为知道这可能是有用的。
UPDATE2 :(更多技术信息) 我正在使用: MS Visual Studio 2010 Ultimate x64 (SP1Rel) Win7 Enterprise SP1 代码是C(但是在c ++开关打开时编译) 子系统:WINDOWS 编译器:cl.exe(使用IDE) 所有其他参数都是默认的。
我使用自修改的入口点(/ENTRY:"entry"
),它是我程序中唯一的功能:
int entry(void)
{
SERVER_INFO_101* si;
DWORD a,b;
NET_API_STATUS c;
c = NetServerEnum ( NULL , 101 , (LPBYTE*) &si , MAX_PREFERRED_LENGTH , &b , &a , SV_TYPE_WORKSTATION, NULL , 0 );
c = NetApiBufferFree (si);
Sleep(1000);
return 0;
}
之前提到的所有测试内容都是在大约100个单位的Windows域网络中进行的。
更新3: 在(非虚拟) WinXP 32位 上进行测试时,不会出现此问题。 (相同的二进制文件,虽然对于Win7 x64两个二进制文件进行了测试 - WOW为32位,原生x64)
答案 0 :(得分:0)
当您使用自定义入口点时,您将绕过运行时库,这意味着您有责任退出该过程。如果没有更多线程在运行,则进程将隐式退出,但正如您所发现的,操作系统可能代表您创建您无法控制的线程。
在您的情况下,您需要做的就是在ExitProcess
函数的末尾显式调用entry()
。
int entry(void)
{
SERVER_INFO_101* si;
DWORD a,b;
NET_API_STATUS c;
c = NetServerEnum ( NULL , 101 , (LPBYTE*) &si , MAX_PREFERRED_LENGTH , &b , &a , SV_TYPE_WORKSTATION, NULL , 0 );
c = NetApiBufferFree (si);
Sleep(1000);
ExitProcess(0);
}
如果没有调用ExitProcess
并使用自定义入口点,您看到的行为就像预期一样。