Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Windows在线程关闭时创建事件_C++_Windows_Multithreading_Unit Testing_Window Handles - Fatal编程技术网

C++ Windows在线程关闭时创建事件

C++ Windows在线程关闭时创建事件,c++,windows,multithreading,unit-testing,window-handles,C++,Windows,Multithreading,Unit Testing,Window Handles,我试图在代码的单元测试框架中添加句柄泄漏检测。(Windows 7,x64 VS2010) 我基本上在每个单元测试之前和之后调用GetProcessHandleCount()。 除了在测试过程中创建/销毁线程外,该方法工作正常 windows似乎偶尔会在线程关闭时创建1-3个事件。在循环中运行相同的测试不会增加事件创建计数。(例如,在循环中运行5000次测试只会产生1-3个额外的事件) 我不会在自己的代码中手动创建事件 这似乎与这个问题类似: 但是我正在手动创建/关闭线程 我遵循了这个准则:

我试图在代码的单元测试框架中添加句柄泄漏检测。(Windows 7,x64 VS2010)

我基本上在每个单元测试之前和之后调用GetProcessHandleCount()。 除了在测试过程中创建/销毁线程外,该方法工作正常

windows似乎偶尔会在线程关闭时创建1-3个事件。在循环中运行相同的测试不会增加事件创建计数。(例如,在循环中运行5000次测试只会产生1-3个额外的事件)

我不会在自己的代码中手动创建事件

这似乎与这个问题类似: 但是我正在手动创建/关闭线程

我遵循了这个准则:

并从WinDbg获得此调用堆栈:

Outstanding handles opened since the previous snapshot:
--------------------------------------
Handle = 0x0000000000000108 - OPEN
Thread ID = 0x00000000000030dc, Process ID = 0x0000000000000c90

0x000000007715173a: ntdll!NtCreateEvent+0x000000000000000a
0x0000000077133f26: ntdll!RtlpCreateCriticalSectionSem+0x0000000000000026
0x0000000077133ee3: ntdll!RtlpWaitOnCriticalSection+0x000000000000014e
0x000000007714e40b: ntdll!RtlEnterCriticalSection+0x00000000000000d1
0x0000000077146ad2: ntdll!LdrShutdownThread+0x0000000000000072
0x0000000077146978: ntdll!RtlExitUserThread+0x0000000000000038
0x0000000076ef59f5: kernel32!BaseThreadInitThunk+0x0000000000000015
0x000000007712c541: ntdll!RtlUserThreadStart+0x000000000000001d
--------------------------------------
如您所见,这是在线程关闭时创建的事件

有没有更好的方法来处理单元测试中的泄漏检测?我目前唯一的选择是:

  • 忘记尝试处理泄漏检测
  • 启动一些虚拟任务,试图创建这些虚假事件
  • 在泄漏中允许一些较小的公差值,并运行每个测试100次(因此实际泄漏将是一个较大的数字)
  • 获取不包括事件的句柄计数(代码量很难)
我也尝试过在VS2013中使用std::thread,但它似乎会在使用时创建很多后台线程和句柄。(使计数差异更大)

下面是一个自包含的示例,其中99%以上的时间(在我的计算机上)事件是在幕后创建的。(句柄计数不同)。将启动/关闭代码放入循环中表示它不会直接泄漏,但会累积偶然事件:

#include "stdio.h"
#include <Windows.h>
#include <process.h>

#define THREADCOUNT 3
static HANDLE s_semCommand, s_semRender;

static unsigned __stdcall ExecutiveThread(void *)
{
  WaitForSingleObject(s_semCommand, INFINITE);
  ReleaseSemaphore(s_semRender, THREADCOUNT - 1, NULL);
  return 0;
}

static unsigned __stdcall WorkerThread(void *)
{
  WaitForSingleObject(s_semRender, INFINITE);
  return 0;
}

int main(int argc, char* argv[])
{
  DWORD oldHandleCount = 0;
  GetProcessHandleCount(GetCurrentProcess(), &oldHandleCount);

  s_semCommand = CreateSemaphoreA(NULL, 0, 0xFFFF, NULL);
  s_semRender  = CreateSemaphoreA(NULL, 0, 0xFFFF, NULL);

  // Spool threads up
  HANDLE threads[THREADCOUNT];
  for (int i = 0; i < THREADCOUNT; i++)
  {
    threads[i] = (HANDLE)_beginthreadex(NULL, 4096, (i==0) ? ExecutiveThread : WorkerThread, NULL, 0, NULL);
  }

  // Signal shutdown - Wait for threads and close semaphores
  ReleaseSemaphore(s_semCommand, 1, NULL);
  for (int i = 0; i < THREADCOUNT; i++)
  {
    WaitForSingleObject(threads[i], INFINITE);
    CloseHandle(threads[i]);
  }
  CloseHandle(s_semCommand);
  CloseHandle(s_semRender);

  DWORD newHandleCount = 0;
  GetProcessHandleCount(GetCurrentProcess(), &newHandleCount);
  printf("Handle %d -> %d", oldHandleCount, newHandleCount);
    return 0;
}
#包括“stdio.h”
#包括
#包括
#定义THREADCOUNT 3
静态句柄s_semCommand,s_semRender;
静态无符号uu stdcall ExecutiveThread(void*)
{
WaitForSingleObject(s_命令,无限);
释放信号量(s_semRender,THREADCOUNT-1,NULL);
返回0;
}
静态无符号\uu stdcall WorkerThread(void*)
{
WaitForSingleObject(s_Semprender,无限);
返回0;
}
int main(int argc,char*argv[])
{
DWORD oldHandleCount=0;
GetProcessHandleCount(GetCurrentProcess(),&oldHandleCount);
s_semCommand=CreateSemaphoreA(NULL,0,0xFFFF,NULL);
s_semRender=CreateSemaphoreA(NULL,0,0xFFFF,NULL);
//线轴向上
处理线程[线程计数];
对于(int i=0;i%d”,旧句柄计数,新句柄计数);
返回0;
}

您可以发布手动线程管理的完整线程启动、运行、等待和清理吗?您描述的单元测试本身是不相关的(除非它是线程进程,但听上去不是)。我怀疑您是否犯了任何严重错误,因为您显然对API很熟悉,但无论如何都值得检查。如果没有其他问题的话,它将导致一个更好的文档化问题。添加了一个可以编译以查看问题的自包含示例。这比预期的更奇怪,我进行了一些调试,发现线程的初始阶段(线程本身)可能会创建一个事件,终止线程可能会创建一个事件。我在Process Explorer中看到了它,并更改了代码,使所有线程都被创建为挂起、恢复、触发、等待、关闭。我加了一些睡眠电话。你介意我对你的问题做些修改吗?@WernerHenze:真的没那么奇怪。这涉及到一个关键部分;关键部分包含事件是很自然的,但为了提高效率,只有在实际需要时才能创建这样的事件。