我有这样的代码:这个同步为什么不起作用?
#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
被调用两次,然后它只是等待。方法永远不会被调用。有人能解释这个僵局的原因吗?
你的例子不是独立的。你不清楚你传递了什么'param'或者你创建了多少个线程。还要注意,你创建了两个事件最初发信号,所以你有一个竞争条件马上。 –
我创建了两个线程。它们都接收一个int作为参数(第一个用0初始化,第二个用1初始化)。这不是问题。我测试过了。 – conectionist
由于两个事件都是在初始状态发出信号的情况下创建的,所以两个线程都同时运行第一次迭代,此时事情就会快速下降。此外,同步代码在完成其清理(重置唤醒事件)之前释放其他线程,这可能会创建其他竞态条件。插入一些打印语句以查看发生了什么。 –