我需要使用原始同步对象解决c ++中的Producer-Consumer问题 - 事件,我已经编写了这段代码
static int g_x = 0;
HANDLE hEvent1;
HANDLE aThread[2];
DWORD ThreadID;
//tread 1
void Producer()
{
for (int i = 0; i < 100; ++i)
{
WaitForSingleObject(hEvent1, INFINITE);
g_x = i;
SetEvent(hEvent1);
}
}
//thread 2
void Consumer()
{
for (;;)
{
WaitForSingleObject(hEvent1, INFINITE);
SetEvent(hEvent1);
}
}
int createthreads() {
hEvent1 = CreateEvent(NULL, FALSE, TRUE, NULL);
// Create worker threads
aThread[0] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)Producer, NULL, 0, &ThreadID);
aThread[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Consumer, NULL, 0, &ThreadID);
}
int main() {
createthreads();
}
此代码无法正常工作:我有无限循环
如何修复此代码以获取从0
到99
的控制台号码?
答案 0 :(得分:1)
您需要另一个事件来同步这两个线程。
另外,我将两个事件的初始状态设置为FALSE
,然后将一个启动事件发送到main
上的生产者线程。
这样您就可以控制进程的启动时间和方式。
Offtopic,createthreads
必须返回一个值。
static int g_x = 0;
HANDLE hEvent1;
HANDLE hEvent2;
HANDLE aThread[2];
DWORD ThreadID;
//tread 1
void Producer()
{
for (int i = 0; i < 100; ++i)
{
WaitForSingleObject(hEvent1, INFINITE);
g_x = i;
SetEvent(hEvent2);
}
}
//thread 2
void Consumer()
{
for (;;)
{
WaitForSingleObject(hEvent2, INFINITE);
SetEvent(hEvent1);
}
}
int createthreads() {
hEvent1 = CreateEvent(NULL, FALSE, FALSE, NULL);
hEvent2 = CreateEvent(NULL, FALSE, FALSE, NULL);
// Create worker threads
aThread[0] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)Producer, NULL, 0, &ThreadID);
aThread[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Consumer, NULL, 0, &ThreadID);
return 0;
}
int main() {
createthreads();
SetEvent(hEvent1);
}
答案 1 :(得分:0)
存在许多实现此任务的方式,一种可能 - 需要使用事件对--2个事件。
struct EventPair
{
HANDLE hLowEvent, hHighEvent;
~EventPair()
{
if (hHighEvent) CloseHandle(hHighEvent);
if (hLowEvent) CloseHandle(hLowEvent);
}
EventPair()
{
hLowEvent = 0, hHighEvent = 0;
}
DWORD Create()
{
return (hLowEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) &&
(hHighEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) ? NOERROR : GetLastError();
}
};
struct SharedData : EventPair
{
int _x;
bool _quit;
SharedData()
{
_x = 0;
_quit = false;
}
static DWORD WINAPI _Producer(void* This)
{
reinterpret_cast<SharedData*>(This)->Producer();
ExitThread(0);
}
void Producer()
{
for (int i = 0; ; )
{
_x = i++;
if (i == 100)
{
_quit = true;
}
SetEvent(hLowEvent);
if (_quit)
{
return;
}
WaitForSingleObject(hHighEvent, INFINITE);
}
}
static DWORD WINAPI _Consumer(void* This)
{
reinterpret_cast<SharedData*>(This)->Consumer();
ExitThread(0);
}
void Consumer()
{
for(;;)
{
WaitForSingleObject(hLowEvent, INFINITE);
DbgPrint("%u\n", _x);
if (_quit)
{
return;
}
SetEvent(hHighEvent);
}
}
};
void testPC()
{
SharedData sd;
if (!sd.Create())
{
HANDLE hThreads[2] = {};
if (hThreads[0] = CreateThread(0, 0, SharedData::_Producer, &sd, 0, 0))
{
if (hThreads[1] = CreateThread(0, 0, SharedData::_Consumer, &sd, 0, 0))
{
WaitForMultipleObjects(2, hThreads, TRUE, INFINITE);
CloseHandle(hThreads[1]);
}
else
{
sd._quit = true;
SetEvent(sd.hHighEvent);
WaitForSingleObject(hThreads[0], INFINITE);
}
}
CloseHandle(hThreads[0]);
}
}