У меня есть этот код:Почему эта синхронизация не работает?
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ITERATIONS 10
typedef struct NUMERE
{
DWORD a;
DWORD b;
} *PNUMERE;
HANDLE ghThreadHandle[2];
HANDLE ghEvents[2];
//HANDLE hEvent;
NUMERE nr;
DWORD WINAPI GenerateNumbers(PNUMERE nr)
{
//PNUMERE nr = ((PNUMERE)param);
if(nr == NULL)
return -1;
nr->a = rand() % 100;
nr->b = (nr->a) * 2;
_tprintf(TEXT("Generated\n"));
//Sleep(10);
return 0;
}
DWORD WINAPI DisplayNumbers(PNUMERE nr)
{
//NUMERE nr = *((PNUMERE)param);
_tprintf(TEXT("Displayed: %d %d\n"),nr->a,nr->b);
return 0;
}
DWORD WINAPI DoStuff(PVOID param)
{
int index = *((int*)param);
for(unsigned int i = 0 ; i < ITERATIONS ; i++)
{
if(index == 0)
{
WaitForSingleObject(ghEvents[1],INFINITE);
ResetEvent(ghEvents[0]);
if(GenerateNumbers(&nr) == -1)
_tprintf(TEXT("GenerateNumbers error!\n"));
SetEvent(ghEvents[0]);
ResetEvent(ghEvents[1]);
}
else
{
WaitForSingleObject(ghEvents[0],INFINITE);
ResetEvent(ghEvents[1]);
DisplayNumbers(&nr);
SetEvent(ghEvents[1]);
ResetEvent(ghEvents[0]);
}
}
return 0;
}
DWORD GenerateThreads()
{
int temp0 = 0, temp1 = 1;
ghThreadHandle[0] = CreateThread(NULL
,0
,(LPTHREAD_START_ROUTINE)DoStuff
,(LPVOID)&temp0
,0
,NULL);
if(NULL == ghThreadHandle[0])
return -1;
ghThreadHandle[1] = CreateThread(NULL
,0
,(LPTHREAD_START_ROUTINE)DoStuff
,(LPVOID)&temp1
,0
,NULL);
if(NULL == ghThreadHandle[1])
{
CloseHandle(ghThreadHandle[0]);
return -1;
}
return 0;
}
int main()
{
srand(time(NULL));
ghEvents[0] = CreateEvent(NULL,TRUE,TRUE,TEXT("MyEvent0"));
ghEvents[1] = CreateEvent(NULL,TRUE,TRUE,TEXT("MyEvent1"));
if(NULL == ghEvents[0] || NULL == ghEvents[1])
{
_tprintf("Error creating events\n");
return -1;
}
if(GenerateThreads() == -1)
{
_tprintf("Error GenerateThreads\n");
return -1;
}
WaitForMultipleObjects(2,ghThreadHandle,TRUE,INFINITE);
//getchar();
CloseHandle(ghThreadHandle[0]);
CloseHandle(ghThreadHandle[1]);
CloseHandle(ghEvents[0]);
CloseHandle(ghEvents[1]);
return 0;
}
Я хочу две функции (GenerateNumbers
и DisplayNumbers
), чтобы назвать в качестве альтернативы. Однако при запуске GenerateNumbers
вызывается дважды, а затем он просто ждет. Метод DisplayNumbers
никогда не вызывается. Может ли кто-нибудь объяснить причину этого тупика?
Ваш пример не является самодостаточным. Неясно, какой «парам» вы передаете или сколько потоков вы создаете. Обратите также внимание на то, что вы создали оба события, которые были первоначально указаны, поэтому у вас есть состояние гонки прямо с места в карьер. –
Создаю два потока. Оба они получают int как параметр (первый инициализируется 0, второй - 1). Это не проблема. Я проверил это. – conectionist
Поскольку оба события создаются с сигналом начального состояния, оба потока одновременно запускают свою первую итерацию, и в этот момент все быстро идет вниз. Кроме того, код синхронизации освобождает другой поток до завершения его очистки (сброса события пробуждения), который может создавать другие условия гонки. Вставьте несколько операторов печати, чтобы узнать, что происходит. –