我正在处理多个生产者和单个消费者问题。我想在线程函数中传递1,2,3线程,以便可以根据这些数字命名单个线程。
但是在创建线程时,程序在第7次计数后崩溃。我认为问题是由于 变量nThreadNo; 如果我将计数限制在7以下就可以正常工作了。但是如果我计算的数量超过了它就会崩溃。
void CEvent1Dlg::CreateProducerThreads()
{
try
{
nThreadNo = new int20];
memset(nThreadNo,0,20);
if (nThreadNo ==NULL) return;
}catch(...)
{
MessageBox(_T("Memory allocation Failed"),_T("Thread"),1);
return ;
}
int i = 0;
for ( i = 0;i<20;i++)
{
//nThreadNo = i+1;
nThreadNo[i] = i+1;
hWndProducer[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ProducerThrdFunc,(void*)(nThreadNo+i),0,&dwProducerThreadID[i]);
if (hWndProducer[i] == NULL)
{
//ErrorHandler(TEXT("CreateThread"));
ExitProcess(3);
}
}
//WaitForMultipleObjects(20,hWndProducer,TRUE,INFINITE);
}
DWORD WINAPI ProducerThrdFunc ( LPVOID n )
{
int *nThreadNo = (int*)n;
char chThreadNo[33];
memset(chThreadNo,0,33);
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,"Producer ");
strcat(pMsg1," Thread No:");
strcat(pMsg1,chThreadNo);
if (stThreadInfoProd.pEventQueue->AddTail(pMsg1)==TRUE)
{
strcpy(pMsg2,"Producer ");
strcat(pMsg2," Thread No:");
strcat(pMsg2,chThreadNo);
strcat(pMsg2," Added the Msg");
}
else
{
strcpy(pMsg2,"Producer ");
strcat(pMsg2," Thread No:");
strcat(pMsg2,chThreadNo);
strcat(pMsg2,"failed to Add the Msg");
}
PostMessage(stThreadInfoProd.hWndHandle,UWM_ONUPDATEPRODUCERLIST,(WPARAM)pMsg2,0);
strcat(pMsg1," Adding Msg:");
//PostMessage(stThreadInfoProd.hWndHandle,UWM_ONUPDATEPRODUCERLIST,(WPARAM)pMsg2,0);
Sleep(3000);
}
return 0;
}
答案 0 :(得分:2)
nThreadNo
的前20个字节归零,而不是应正在执行的第一个20 * sizeof(int)
字节。hWndProducer
,dwProducerThreadID
。这些中还有足够的元素吗?答案 1 :(得分:1)
CreateThread
调用正在传递整数值,但线程函数本身将其视为指向整数的指针。而不是这个:
int *nThreadNo = (int*)n;
应该是:
int nThreadNo = (int)n;
编辑:我仔细查看了调用,我确实看到它传递了一个整数指针。但是,该值是堆栈数据,在线程尝试读取它时可能不存在。所以它应该只传递整数值:(void*)(nThreadNo[i])
答案 2 :(得分:0)
这一行
if (nThreadNo ==NULL) return;
毫无价值。
现代C ++中的new
运算符在失败时不返回NULL,它会抛出std::badalloc
异常,但即使您使用返回NULL的分配器来指示失败,也为时已晚检测到它,你已经将NULL指针传递给memcpy
。