让我烦恼多天的线程问题

hainanxu 2008-04-30 09:10:47


void CDomainG::OnTimer(UINT nIDEvent)
{

MyDefStr glTagMsg[10000];
// TODO: Add your message handler code here and/or call default
CEdit *CEXECUTE_TIME=(CEdit*)GetDlgItem(IDC_EDIT_EXECUTE_TIME);
CTime time=CTime::GetCurrentTime();
CEXECUTE_TIME->SetWindowText(time.Format("%Y-%m-%d %H:%M:%S"));

if(theApp.m_CONDITIONS=="现在执行")
{

if(thDomain=="1"){
thDomain="0";
for(int i=0;i<10;i++){

glTagMsg[i].pDlg=this;
glTagMsg[i].DomainName_c_i=i;


CWinThread* pThread =AfxBeginThread(MyThread,&glTagMsg[i],THREAD_PRIORITY_IDLE);


}

}
}else{
if(thDomain=="1"&&time.Format("%H:%M:%S")>theApp.m_starttime&&time.Format("%H:%M:%S")<theApp.m_overtime){

for(int i=0;i<10;i++){

glTagMsg[i].pDlg=this;
glTagMsg[i].DomainName_c_i=i;


CWinThread* pThread = AfxBeginThread(MyThread,&glTagMsg[i],THREAD_PRIORITY_IDLE);



}

}
}


CDialog::OnTimer(nIDEvent);
}



运行错误提示unknown software exception (0x80000003),位置0x7c921230


请高手们帮我解决一下.具体有点代码
...全文
180 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
UltraBejing 2008-05-01
  • 打赏
  • 举报
回复
我也想了解,谢谢LZ.
meiZiNick 2008-05-01
  • 打赏
  • 举报
回复
有问题请先GOOGLE,BAIDU
yawer 2008-04-30
  • 打赏
  • 举报
回复
你的线程执行函数呢?只看到了你起了10个线程。这10个线程之间是无序的竞争资源的,你好像也没有做线程的同步。
ouyh12345 2008-04-30
  • 打赏
  • 举报
回复
MyDefStr glTagMsg[10000];

有必要开这么大的数组吗?
iGoo 2008-04-30
  • 打赏
  • 举报
回复
访问0x7c921230这个位置肯定是,越界访问了
zhacker 2008-04-30
  • 打赏
  • 举报
回复
MyDefStr glTagMsg[10000];

有必要开这么大的数组吗?

还有两个for(int i=0;i<10;i++)
都是用的int i ;不怎么明白?
winsock22 2008-04-30
  • 打赏
  • 举报
回复
整理了一下代码!供你参考!
#define WORKTHREADNUM 10
typedef struct{
MyDefStr *pglTagMsg; //自己定义的一个类型指针
HANDLE *phThreads; //存放一组线程句柄(用于等候这组线程结束)
}MYDEFSTRANDHANDLE,*LPMYDEFSTRANDHANDLE;
UINT DoDeleteThreadProc(LPVOID pParam); //专门用来释放空间的线程执行函数
....
void CDomainG::BatchCreateWorkThread(int nWorkThreadNum)
{
LPMYDEFSTRANDHANDLE lpMyDefStrAndHandle=new MYDEFSTRANDHANDLE; //分配空间
lpMyDefStrAndHandle->pglTagMsg=new MyDefStr[nWorkThreadNum]; //分配空间
lpMyDefStrAndHandle->phThreads=new HANDLE[nWorkThreadNum]; //分配空间
for(int i=0;i<nWorkThreadNum;i++){
lpMyDefStrAndHandle->glTagMsg[i].pDlg=this;
lpMyDefStrAndHandle->glTagMsg[i].DomainName_c_i=i;
CWinThread* pThread =AfxBeginThread(MyThread,(LPVOID)&lpMyDefStrAndHandle->glTagMsg[i],THREAD_PRIORITY_IDLE);
lpMyDefStrAndHandle->phThreads[i]=pThread->m_hThread;
}
AfxBeginThread(DoDeleteThreadProc,(LPVOID)lpMyDefStrAndHandle,THREAD_PRIORITY_IDLE);//创建一个专门用来释放空间的线程
}
void CDomainG::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CEdit *CEXECUTE_TIME=(CEdit*)GetDlgItem(IDC_EDIT_EXECUTE_TIME);
CTime time=CTime::GetCurrentTime();
CEXECUTE_TIME->SetWindowText(time.Format("%Y-%m-%d %H:%M:%S"));
if(theApp.m_CONDITIONS=="现在执行")
{

if(thDomain=="1"){
thDomain="0";
BatchCreateWorkThread(WORKTHREADNUM);
}

}else{
if(thDomain=="1"&&time.Format("%H:%M:%S")>theApp.m_starttime&&time.Format("%H:%M:%S")<theApp.m_overtime){
BatchCreateWorkThread(WORKTHREADNUM);
}
}
CDialog::OnTimer(nIDEvent);
}

释放空间的线程执行函数如下:
UINT DoDeleteThreadProc(LPVOID pParam)
{
LPMYDEFSTRANDHANDLE lpMyDefStrAndHandle=(LPMYDEFSTRANDHANDLE)pParam;
WaitForMultipleObjects(WORKTHREADNUM,lpMyDefStrAndHandle->phThreads,true,INFINITE);//守候先前OnTimer中创建的所有线程结束
delete [] lpMyDefStrAndHandle->MyDefStr; //释放空间
delete [] lpMyDefStrAndHandle->phThreads; //释放空间
delete lpMyDefStrAndHandle; //释放空间
return 0;
}
skyful123 2008-04-30
  • 打赏
  • 举报
回复
MyDefStr glTagMsg[10000];
TIME函数结束 这个就释放咯
winsock22 2008-04-30
  • 打赏
  • 举报
回复
问题在这里了
MyDefStr glTagMsg[10000];
用AfxBeginThread创建的线程是异步运行的.当前线程在OnTimer函数返回后,局部数组glTagMsg将被撤消.在这以后,对这块内存区域的访问将是维规的.

可以这样:
#define MAXNUM 10
typedef struct{
MyDefStr *pglTagMsg; //自己定义的一个类型指针
HANDLE *phThreads; //存放一组线程句柄
}MYDEFSTRANDHANDLE,*LPMYDEFSTRANDHANDLE;
...
void CDomainG::OnTimer(UINT nIDEvent)
{

LPMYDEFSTRANDHANDLE lpMyDefStrAndHandle=new MYDEFSTRANDHANDLE; //分配
lpMyDefStrAndHandle->pglTagMsg=new MyDefStr[MAXNUM]; //分配
lpMyDefStrAndHandle->phThreads=new HANDLE[MAXNUM]; //分配
// TODO: Add your message handler code here and/or call default
CEdit *CEXECUTE_TIME=(CEdit*)GetDlgItem(IDC_EDIT_EXECUTE_TIME);
CTime time=CTime::GetCurrentTime();
CEXECUTE_TIME->SetWindowText(time.Format("%Y-%m-%d %H:%M:%S"));

if(theApp.m_CONDITIONS=="现在执行")
{

if(thDomain=="1"){
thDomain="0";
for(int i=0;i<MAXNUM;i++){
lpMyDefStrAndHandle->glTagMsg[i].pDlg=this;
lpMyDefStrAndHandle->glTagMsg[i].DomainName_c_i=i;
CWinThread* pThread =AfxBeginThread(MyThread,(LPVOID)&lpMyDefStrAndHandle->glTagMsg[i],THREAD_PRIORITY_IDLE);
lpMyDefStrAndHandle->phThreads[i]=pThread->m_hThread;
}
AfxBeginThread(DoDeleteThreadProc,(LPVOID)lpMyDefStrAndHandle,THREAD_PRIORITY_IDLE);//创建一个专门用来释放空间的线程
}
else{
delete [] lpMyDefStrAndHandle->MyDefStr; //释放
delete [] lpMyDefStrAndHandle->hThreads; //释放
delete lpMyDefStrAndHandle; //释放
}
}else{
//同样
if(thDomain=="1"&&time.Format("%H:%M:%S")>theApp.m_starttime&&time.Format("%H:%M:%S")<theApp.m_overtime){

for(int i=0;i<MAXNUM;i++){

lpMyDefStrAndHandle->glTagMsg[i].pDlg=this;
lpMyDefStrAndHandle->glTagMsg[i].DomainName_c_i=i;


CWinThread* pThread = AfxBeginThread(MyThread,(LPVOID)&glTagMsg[i],THREAD_PRIORITY_IDLE);
lpMyDefStrAndHandle->phThreads[i]=pThread->m_hThread;


}
AfxBeginThread(DoDeleteThreadProc,(LPVOID)lpMyDefStrAndHandle,THREAD_PRIORITY_IDLE);
}
else{
delete [] lpMyDefStrAndHandle->MyDefStr;
delete [] lpMyDefStrAndHandle->hThreads;
delete lpMyDefStrAndHandle;
}
}
CDialog::OnTimer(nIDEvent);
}

释放空间的线程执行函数如下:
UINT DoDeleteThread( LPVOID pParam)
{
LPMYDEFSTRANDHANDLE lpMyDefStrAndHandle=(LPMYDEFSTRANDHANDLEp)Param;
WaitForMultipleObjects(MAXNUM,lpMyDefStrAndHandle->phThreads,true,INFINITE); //守候OnTimer中创建的所有线程结束
delete [] lpMyDefStrAndHandle->MyDefStr; //释放
delete [] lpMyDefStrAndHandle->hThreads; //释放
delete lpMyDefStrAndHandle; //释放
return 0;
}
//前面部分的代码有些冗余,相同的部分写到一个函数里面要舒服些。这里仅仅表达一下思路!





jwybobo2007 2008-04-30
  • 打赏
  • 举报
回复
大家都挺热心的啊
jameshooo 2008-04-30
  • 打赏
  • 举报
回复
这段代码很眼熟,前段时间才看见过,实在想不通为什么在定时器里创建线程,而且每次创建10个,又没有看见在哪取消定时器,无语……
cnzdgs 2008-04-30
  • 打赏
  • 举报
回复
MyDefStr glTagMsg[10000];
这是局部动态变量,函数返回后就释放了,不能作为线程参数,否则后果无法预料。如果要这样用,必须确保在线程访问它时函数还没有返回(函数执行等待函数等待线程退出或者等待线程信号),或者用new来分配,由线程负责delete。

15,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧