簡體   English   中英

消費者生產者線程問題

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM