问题描述
(简而言之:main()的WaitForSingleObject挂在下面的程序中).
(In short: main()'s WaitForSingleObject hangs in the program below).
我正在尝试编写一段代码来分派线程并等待它们完成后再恢复.我没有每次都创建线程,这很昂贵,而是让它们进入睡眠状态.主线程创建 X 个处于 CREATE_SUSPENDED 状态的线程.
I'm trying to write a piece of code that dispatches threads and waits for them to finish before it resumes. Instead of creating the threads every time, which is costly, I put them to sleep. The main thread creates X threads in CREATE_SUSPENDED state.
同步是使用以 X 作为最大计数的信号量完成的.信号量的计数器被归零,线程被分派.线程执行一些愚蠢的循环并在它们进入睡眠之前调用 ReleaseSemaphore.然后主线程使用WaitForSingleObject X 次来确保每个线程都完成了它的工作并且正在休眠.然后它循环并再次执行所有操作.
The synch is done with a semaphore with X as MaximumCount. The semaphore's counter is put down to zero and the threads are dispatched. The threds perform some silly loop and call ReleaseSemaphore before they go to sleep. Then the main thread uses WaitForSingleObject X times to be sure every thread finished its job and is sleeping. Then it loops and does it all again.
程序有时不会退出.当我对程序进行喙时,我可以看到 WaitForSingleObject 挂起.这意味着线程的 ReleaseSemaphore 不起作用.没有任何东西是 printf'ed 所以应该没有出错.
From time to time the program does not exit. When I beak the program I can see that WaitForSingleObject hangs. This means that a thread's ReleaseSemaphore did not work. Nothing is printf'ed so supposedly nothing went wrong.
也许两个线程不应该同时调用 ReleaseSemaphore,但这会使信号量的用途无效...
Maybe two threads shouldn't call ReleaseSemaphore at the exact same time, but that would nullify the purpose of semaphores...
我只是不了解它......
I just don't grok it...
非常感谢您接受其他同步线程的解决方案!
Other solutions to synch threads are gratefully accepted!
#define TRY 100
#define LOOP 100
HANDLE *ids;
HANDLE semaphore;
DWORD WINAPI Count(__in LPVOID lpParameter)
{
float x = 1.0f;
while(1)
{
for (int i=1 ; i<LOOP ; i++)
x = sqrt((float)i*x);
while (ReleaseSemaphore(semaphore,1,NULL) == FALSE)
printf(" ReleaseSemaphore error : %d ", GetLastError());
SuspendThread(ids[(int) lpParameter]);
}
return (DWORD)(int)x;
}
int main()
{
SYSTEM_INFO sysinfo;
GetSystemInfo( &sysinfo );
int numCPU = sysinfo.dwNumberOfProcessors;
semaphore = CreateSemaphore(NULL, numCPU, numCPU, NULL);
ids = new HANDLE[numCPU];
for (int j=0 ; j<numCPU ; j++)
ids[j] = CreateThread(NULL, 0, Count, (LPVOID)j, CREATE_SUSPENDED, NULL);
for (int j=0 ; j<TRY ; j++)
{
for (int i=0 ; i<numCPU ; i++)
{
if (WaitForSingleObject(semaphore,1) == WAIT_TIMEOUT)
printf("Timed out !!!
");
ResumeThread(ids[i]);
}
for (int i=0 ; i<numCPU ; i++)
WaitForSingleObject(semaphore,INFINITE);
ReleaseSemaphore(semaphore,numCPU,NULL);
}
CloseHandle(semaphore);
printf("Done
");
getc(stdin);
}
推荐答案
问题出现在以下情况:
主线程恢复工作线程:
for (int i=0 ; i<numCPU ; i++)
{
if (WaitForSingleObject(semaphore,1) == WAIT_TIMEOUT)
printf("Timed out !!!
");
ResumeThread(ids[i]);
}
工作线程完成它们的工作并释放信号量:
the worker threads do their work and release the semaphore:
for (int i=1 ; i<LOOP ; i++)
x = sqrt((float)i*x);
while (ReleaseSemaphore(semaphore,1,NULL) == FALSE)
主线程等待所有工作线程并重置信号量:
the main thread waits for all worker threads and resets the semaphore:
for (int i=0 ; i<numCPU ; i++)
WaitForSingleObject(semaphore,INFINITE);
ReleaseSemaphore(semaphore,numCPU,NULL);
主线程进入下一轮,试图恢复工作线程(请注意,工作线程还没有暂停自己的事件!这是问题开始的地方......你正在尝试恢复那些没有的线程)不一定要暂停):
the main thread goes into the next round, trying to resume the worker threads (note that the worker threads haven't event suspended themselves yet! this is where the problem starts... you are trying to resume threads that aren't necessarily suspended yet):
for (int i=0 ; i<numCPU ; i++)
{
if (WaitForSingleObject(semaphore,1) == WAIT_TIMEOUT)
printf("Timed out !!!
");
ResumeThread(ids[i]);
}
最后,工作线程暂停自己(虽然他们应该已经开始下一轮):
finally the worker threads suspend themselves (although they should already start the next round):
SuspendThread(ids[(int) lpParameter]);
并且主线程永远等待,因为现在所有工作人员都被挂起:
and the main thread waits forever since all workers are suspended now:
for (int i=0 ; i<numCPU ; i++)
WaitForSingleObject(semaphore,INFINITE);
这里有一个链接,展示了如何正确解决生产者/消费者问题:
here's a link that shows how to correctly solve producer/consumer problems:
http://en.wikipedia.org/wiki/Producer-consumer_problem
我也认为 关键部分是比信号量和互斥量快得多.在大多数情况下,它们也更容易理解 (imo).
also i think critical sections are much faster than semaphores and mutexes. they're also easier to understand in most cases (imo).
这篇关于ReleaseSemaphore 不释放信号量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!