简体   繁体   English

消费者生产者线程问题

[英]Consumer producer Thread Issue

I am working on Single Producer Single Consumer Problem.Here producer thread will write to the list and consumer thread remove it from list. 我正在研究单一生产者单一消费者问题。生产者线程将在此处写入列表,消费者线程将其从列表中删除。 I have dialog box where i maintain two list 1.consumer list box 2.producer list box, which will list the message posted by both thread.I am getting strange problem here.Here message are get mixed up with each other.Consumer thread is also getting message of the Producer apart from consumer thread message thread and vice versa. 我有一个对话框,其中我维护两个列表1.消费者列表框2.生产者列表框,该列表将列出两个线程发布的消息。我在这里遇到了奇怪的问题。这里的消息相互混淆。消费者线程是除使用者线程消息线程外,还获得生产者的消息,反之亦然。

I am passing THREADINFO from main thread 我正在从主线程传递THREADINFO

can any body suggest me what went wrong here.I am passing correct thread name from main thread but when it comes to Producer or Consumer Thread sometime value getting changed. 任何人都可以建议我这里出了什么问题。我从主线程传递了正确的线程名称,但是当涉及到生产者线程或消费者线程时,值有时会被更改。 I have two thread given below 我下面有两个线程

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;
}

How is your THREADINFO struct constructed? 您的THREADINFO结构如何构造? On the local stack in the function where you create the struct, on a global level of the stack, or on the heap? 在创建结构的函数的本地堆栈上,在堆栈的全局级别上还是在堆上? It's possible that the THREADINFO instance go out of scope before it's accesed on the worker threads. THREADINFO实例在进入工作线程之前可能超出范围。

There is a lot wrong with this code. 此代码有很多错误。

In your producer thread, you are doing the following: 在生产者线程中,您正在执行以下操作:

stThreadInfoProd->pEventQueue->AddTail(pMsg1);

and unless the AddTail is being clever, this is adding the pointer to the queue, it is not duplicating the string. 除非AddTail很聪明,否则这是将指针添加到队列中,因此不会复制字符串。 Then, in your consumer you're doing this: 然后,在您的消费者中,您正在执行以下操作:

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

which is getting the pointer you added to the queue. 这将获取您添加到队列的指针。 This points to the buffer you're using for the producer messages, so when you do this in the consumer: 这指向您用于生产者消息的缓冲区,因此在使用者中执行此操作时:

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

you are overwriting the producer's buffer. 您正在覆盖生产者的缓冲区。 I think what you wanted is more like this: 我认为您想要的更像是这样:

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

and then the following lines won't overwrite the producer's data. 然后以下几行将不会覆盖生产者的数据。

But this introduces another problem. 但这引入了另一个问题。 In your producer you do this: 在生产者中,您可以执行以下操作:

stThreadInfoProd->pEventQueue->AddTail(pMsg1);

which adds the pointer to the queue and then immediately do this: 这会将指针添加到队列,然后立即执行此操作:

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

which overwrites the buffer. 覆盖缓冲区。 This overwrite will almost certainly occur before the consumer has had a chance to consume the message, so the consumer will read the modified buffer, not the message you originally sent. 这种覆盖几乎肯定会在使用者有机会使用消息之前发生,因此使用者将读取修改后的缓冲区,而不是您最初发送的消息。 To solve this, change the producer thus: 要解决此问题,请更改生产者:

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

The strdup creates a copy of the contents of the buffer pMsg1 points to. strdup创建缓冲区pMsg1指向的内容的副本。

The consumer then needs to be: 消费者则需要:

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