NetServerEnum创建不会关闭的工作线程

时间:2013-06-12 15:32:33

标签: windows networking thread-safety threadpool netapi32

在尝试解决之前提到的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)

1 个答案:

答案 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并使用自定义入口点,您看到的行为就像预期一样。