有一次在项目中遇到一个问题, 发现有些线程始终得不到运行,
而有些线程早已运行了很多次, 于是我猜测是否是因为抢锁不均匀导致的.
于是写了一下测验代码, 经过验证, 确实存在这个问题.
下面的例子说明, 当等锁的线程达到几百个的时候,
很容易导致有些线程很长的时间都抢不到锁, 而有些线程却反复的获得锁.
static void dbg_printf(const char *format, ...)
{
char StrBuf[512];
va_list ap;
va_start(ap, format);
_vsnprintf_s(StrBuf, sizeof(StrBuf), format, ap);
va_end(ap);
OutputDebugStringA(StrBuf);
}
CRITICAL_SECTION g_cs;
static unsigned int WINAPI ThreadFunc(LPVOID inThread)
{
for(int i = 0; i < THREAD_RUN_TIME; ++i)
{
DWORD tick = GetTickCount();
dbg_printf("[tick:0x%08x][tid:%08x][enter lock]\r\n", tick, GetCurrentThreadId());
EnterCriticalSection(&g_cs);
dbg_printf("[tick:0x%08x][tid:%08x][enter lock suc:%d]\r\n", tick, GetCurrentThreadId(), GetTickCount()-tick);
LeaveCriticalSection(&g_cs);
dbg_printf("[tick:0x%08x][tid:%08x][leave lock]\r\n", tick, GetCurrentThreadId());
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
InitializeCriticalSection(&g_cs);
for (int nThreadCount = 0; nThreadCount < MAX_THREAD_COUNT; nThreadCount++)
{
HANDLE hThread = (HANDLE)_beginthreadex( NULL, // Inherit security
0, // Inherit stack size
ThreadFunc, // Entry function
(void* )nThreadCount, // Entry arg
0, // Begin executing immediately
0 );
CloseHandle(hThread);
}
getchar();
return 0;
}
如果想改善这个问题, 可以使用task队列+线程池的方式来运行.