我在这里使用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;
}
答案 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必须是全局的,因为你给它指向新线程的指针。