[英]Consumer producer Thread Issue
我正在研究單一生產者單一消費者問題。生產者線程將在此處寫入列表,消費者線程將其從列表中刪除。 我有一個對話框,其中我維護兩個列表1.消費者列表框2.生產者列表框,該列表將列出兩個線程發布的消息。我在這里遇到了奇怪的問題。這里的消息相互混淆。消費者線程是除使用者線程消息線程外,還獲得生產者的消息,反之亦然。
我正在從主線程傳遞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;
}
您的THREADINFO
結構如何構造? 在創建結構的函數的本地堆棧上,在堆棧的全局級別上還是在堆上? THREADINFO
實例在進入工作線程之前可能超出范圍。
此代碼有很多錯誤。
在生產者線程中,您正在執行以下操作:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.