2017-04-03 29 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]); 
    } 
}