(Вкратце: main() WaitForSingleObject висит в программе ниже).ReleaseSemaphore не освобождает семафор
Я пытаюсь написать фрагмент кода, который отправляет потоки и ждет их завершения до его возобновления. Вместо того, чтобы создавать потоки каждый раз, что дорого, я их спал. Основной поток создает потоки X в состоянии CREATE_SUSPENDED.
Синхронизация выполняется с помощью семафора с X как MaximumCount. Счётчик семафора сбрасывается до нуля, и потоки отправляются. The threds выполняют какую-то глупую петлю и вызывают ReleaseSemaphore, прежде чем они отправятся спать. Затем основной поток использует WaitForSingleObject X раз, чтобы убедиться, что каждый поток завершил свою работу и спал. Затем он петляет и делает все это снова.
Время от времени программа не выходит. Когда я клюю программу, я вижу, что WaitForSingleObject зависает. Это означает, что поток ReleaseSemaphore в потоке не работал. Ничего не напечатано, так что, мол, ничто не пошло не так.
Может быть две нити не должно называть ReleaseSemaphore в то же самое время, но это было бы свести на нет цели семафоров ...
я просто не обращал внимание на это ...
Других решений для синхронизирующие потоки с благодарностью принимаются!
#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 !!!\n");
ResumeThread(ids[i]);
}
for (int i=0 ; i<numCPU ; i++)
WaitForSingleObject(semaphore,INFINITE);
ReleaseSemaphore(semaphore,numCPU,NULL);
}
CloseHandle(semaphore);
printf("Done\n");
getc(stdin);
}
Ницца теория/описание. Помещение основной в спящий режим (1), прежде чем возобновление потоков, похоже, решает проблему, но тогда производительность не ушла. По крайней мере, это подтверждает теорию: основные потоки возобновления, которые еще не спали \ o / – Gabriel