2011-03-03 226 views
0

我正在處理單生產者單消費者問題。這裏的生產者線程將寫入列表,消費者線程將其從列表中移除。 我有對話框,其中我維護兩個清單1.消費者列表框2.producer列表框,這將列出這兩個線程發佈的消息。我在這裏得到奇怪的問題。這裏的消息被混淆了彼此。消費者線程也從消費者線程消息線程獲取生產者消息,反之亦然。消費者生產者線程問題

我傳遞的ThreadInfo從主線程

任何機構可以建議我出了什麼問題我這兒過得從主線程傳遞正確的線程的名字,但是當涉及到生產者或消費者線程有時價值得到改變。 我有兩個螺紋下方

typedef struct THREADINFO{ 
    CEventQueue* pEventQueue; 
    HWND hWndHandle; 
    char* pThreadName; 
}THREADINFO 
DWORD WINAPI ProducerThrdFunc (LPVOID n) 
{ 
    THREADINFO* stThreadInfoProd = (THREADINFO*)n; 
    char* pMsg1 = new char[100]; 
    while(1) 
    { 

     strcpy(pMsg1,stThreadInfoProd->pThreadName); 
     strcat(pMsg1," Thread No:");   
     strcat(pMsg1,"Adding Msg"); 

     PostMessage(stThreadInfoProd->hWndHandle,UWM_ONUPDATEPRODUCERLIST,(WPARAM)pMsg1,0); 

     stThreadInfoProd->pEventQueue->AddTail(pMsg1); 
     memset(pMsg1,0,100); 

     strcpy(pMsg1,stThreadInfoProd->pThreadName); 
     strcat(pMsg1,"Thread No:");  
     strcat(pMsg1,"Added Msg"); 
     char*p = "Producer"; 
     PostMessage(stThreadInfoProd->hWndHandle,UWM_ONUPDATEPRODUCERLIST,(WPARAM)pMsg1,0); 

     Sleep(3000); 
    } 
    return 0; 
} 

DWORD WINAPI ConsumerThrdFunc (LPVOID n) 
{ 
    THREADINFO* stThreadInfoCons = (THREADINFO*)n; 

    char* pMsg = new char[100]; 
    memset(pMsg,0,100); 

    while(1) 
    { 
     strcpy(pMsg,stThreadInfoCons->pThreadName); 
     strcat(pMsg," Thread No:"); 
     strcat(pMsg,"Removing Msg");   
     PostMessage(stThreadInfoCons->hWndHandle,UWM_ONUPADTECONSUMERLIST,(WPARAM)pMsg,0); 

     memset(pMsg,0,100); 

     char *pMsg = (char*)stThreadInfoCons->pEventQueue->RemoveHead();   
     strcpy(pMsg,stThreadInfoCons->pThreadName); 
     strcat(pMsg,"Thread No:"); 
     strcat(pMsg,"Removed Msg"); 

     PostMessage(stThreadInfoCons->hWndHandle,UWM_ONUPADTECONSUMERLIST,(WPARAM)pMsg,0); 
     Sleep(3000); 
    } 
    return 0; 
} 
+0

顯示代碼分別啓動線程,並通過一個ThreadInfo的說法,應該有問題。 – Fox32 2011-03-03 07:57:54

+0

你的意思是「有時候值得改變」? – Fox32 2011-03-03 09:48:48

回答

0

給您THREADINFO結構是如何構建的?在創建結構的函數的本地堆棧中,堆棧的全局級別還是堆上? 在工作線程上加入之前,THREADINFO實例可能超出範圍。

+0

我正在主線程中創建THREADINFO結構並將其作爲線程參數傳遞。 – 2011-03-03 09:30:51

+0

如何?使用新的還是本地的?添加代碼。 – Fox32 2011-03-03 09:38:37

+0

我在主線程類中創建成員變量THREADINFO stThreadInfoProd; \t THREADINFO stThreadInfoCons;一個用於生產者線程,另一個用於消費者線程。 – 2011-03-03 09:44:15

0

這段代碼有很多錯誤。

在您的生產者線程,你正在做以下幾點:

stThreadInfoProd->pEventQueue->AddTail(pMsg1); 

並且除非AddTail正在巧妙,這是在加入的指針隊列,不重複的字符串。然後,在你的消費者,你這樣做:

char *pMsg = (char*)stThreadInfoCons->pEventQueue->RemoveHead(); 

這是獲取您添加到隊列的指針。這指向您使用的是生產者消息的緩衝區,所以當你做到這一點在消費:

strcpy(pMsg,stThreadInfoCons->pThreadName); 
strcat(pMsg,"Thread No:"); 
strcat(pMsg,"Removed Msg"); 

要覆蓋生產的緩衝區。我想你想要的更像是這樣的:

char *pProducerMsg = (char*)stThreadInfoCons->pEventQueue->RemoveHead(); 

然後下面的行不會覆蓋生產者的數據。

但是這引出了另一個問題。在你製作你這樣做:

stThreadInfoProd->pEventQueue->AddTail(pMsg1); 

它增加了指針的隊列,然後立即這樣做:

memset(pMsg1,0,100); 
strcpy(pMsg1,stThreadInfoProd->pThreadName); 
strcat(pMsg1,"Thread No:");  
strcat(pMsg1,"Added Msg"); 

這將覆蓋緩衝區。這種覆蓋幾乎肯定會在消費者有機會使用消息之前發生,因此消費者將讀取修改後的緩衝區,而不是您最初發送的消息。爲了解決這個問題,從而改變生產者:

stThreadInfoProd->pEventQueue->AddTail(strdup(pMsg1)); 

的的strdup創建的緩衝pMsg1點到的內容的副本。

消費者則需要爲:

char *pProducerMsg = (char*)stThreadInfoCons->pEventQueue->RemoveHead(); 
// do something with pProducerMsg 
free (pProducerMsg); // strdup calls malloc, so a matching free is required