2017-04-03 59 views
1

我需要解决在C生产者 - 消费者问题++使用基本同步对象 - 事件,我已经写了这个代码如何解决在C++中使用winapi事件的生产者 - 消费者?

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(); 
} 

此代码不能正常工作:我有无限循环 我怎样才能解决这个代码要获得从099的控制台号码?

+0

https://msdn.microsoft.com/en-us/library/windows/desktop/ms686903(v=vs.85).aspx –

+0

https://msdn.microsoft.com/en-us /library/windows/desktop/aa904937(v=vs.85).aspx –

+0

这种类型的代码需要使用2个事件 – RbMm

回答

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); 
} 
+0

'createthreads必须返回一个值'并且必须带有一个参数* __stdcall * – RbMm

+0

两个线程都开始来自* WaitForSingleObject * - 在这种情况下都挂起。需要一个* SetEvent *先致电 – RbMm

+0

@RbMm,是的,你需要那个! – Rama

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]); 
    } 
}