线程显示不一致的结果

时间:2011-03-04 11:28:59

标签: c++ multithreading

我在这里使用ThrdFunc创建5个线程。这里每个线程都会更新listBox。

我以这种方式期待着消息。最初以这种方式出现但是过了一段时间

Thread1:Adding msg
Thread2:Adding msg
Thread3:Adding msg

但是过了一段时间我得到了像

这样的消息
Thread0:Adding msg
Thread18967654:Adding msg
Thread18967654:Adding msg
Thread18967654:Adding msg

这是代码:

for (int i = 0;i<6;i++)
    {   
        nThreadNo = i+1;
        hWndProducer[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ProducerThrdFunc,(void*)&nThreadNo,0,&dwProducerThreadID[i]);     
        if (hWndProducer[i] == NULL) 
        {
           //ErrorHandler(TEXT("CreateThread"));
           ExitProcess(3);
        }
    }   

DWORD WINAPI    ThrdFunc ( LPVOID n )
{
    int *nThreadNo = (int*)n;       
    char chThreadNo[3];
    memset(chThreadNo,0,3);

    while(1)
    {
        itoa(*nThreadNo,chThreadNo,10);
        char* pMsg1 = new char[100];
        char* pMsg2 = new char[100];
        memset(pMsg1,0,100);
        memset(pMsg2,0,100);

        strcpy(pMsg1," Thread No:");        
        strcat(pMsg1,chThreadNo);
        strcat(pMsg1," Adding Msg:");

        PostMessage(stThreadInfoProd.hWndHandle,UWM_ONUPDATEPRODUCERLIST,(WPARAM)pMsg1,0);


    }   
    return 0;
}

3 个答案:

答案 0 :(得分:3)

嗯,我无法确定,因为你没有提供所有代码。

然而,看起来nThreadNo是一个局部变量,在主线程的堆栈上定义。您将此变量的地址传递给线程,但您应该传递该值,或传递一些堆分配的内存。

你在做什么在道德上等同于从函数返回指向局部变量的指针,例如

int* foo()
{
    int i;
    return &i;
}

使代码行为的最简单方法是进行以下更改:

CreateThread(..., (void*)nThreadNo, ...

int nThreadNo = (int)n;

答案 1 :(得分:3)

最有可能在堆栈上分配nThreadNo。你给每个线程一个指向其中一个元素的指针。

创建线程的函数返回后,数组不再有效,但线程函数仍指向它。线程持有指针的内存最有可能被覆盖,导致最初的线程ID被垃圾覆盖。

通过另一个线程的任何内容通常应该在堆上分配,可以通过malloc类型函数或new,最好是new,因为这是C ++。

例如,使用int nThreadNo[6]而不是int* nThreadNo = new int[6]。但是,请注意,当您完成记忆时,您需要delete[]个记忆nThreadNo

答案 2 :(得分:1)

nThreadNo必须是全局的,因为你给它指向新线程的指针。