C++ 消费者-生产者线程问题

C++ 消费者-生产者线程问题,c++,winapi,C++,Winapi,我正在处理单生产者单消费者问题。在这里,生产者线程将写入列表,消费者线程将其从列表中删除。 我有一个对话框,其中我维护了两个列表1.消费者列表框2.生产者列表框,它将列出两个线程发布的消息。我在这里遇到了奇怪的问题。这里的消息相互混淆。消费者线程除了消费者线程消息线程外,还获取生产者的消息,反之亦然 我正在从主线程传递THREADINFO 有谁能告诉我这里出了什么问题。我正在从主线程传递正确的线程名称,但当涉及到生产者或消费者线程时,有时值会发生变化。 我有下面给出的两条线 typedef st

我正在处理单生产者单消费者问题。在这里,生产者线程将写入列表,消费者线程将其从列表中删除。 我有一个对话框,其中我维护了两个列表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
struct是如何构造的?在创建结构的函数的本地堆栈上,在堆栈的全局级别上,还是在堆上?
THREADINFO
实例在工作线程上进行访问之前可能超出范围。

此代码有很多错误

在producer线程中,您正在执行以下操作:

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

显示代码如果启动线程并传递THREADINFO参数,则应该存在问题。您所说的“有时值被更改”是什么意思?我正在主线程中创建THREADINFO结构并将其作为线程参数传递。我正在主线程类中创建成员变量THREADINFO stThreadInfoProd;THREADINFO stThreadInfoCons;一个用于生产者线程,一个用于消费者线程。