首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 高分请教时间多线程问题 [无满意答案结贴]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 15:03:13 楼主
    C/C++ code
    /********************************************************************************/ typedef struct MyDefStr { CDomainG* pDlg ; int DomainName_c_i; }MyDefStr; typedef struct { MyDefStr *glTagMsg; //自己定义的一个类型指针 HANDLE *phThreads; //存放一组线程句柄 }MYDEFSTRANDHANDLE,*LPMYDEFSTRANDHANDLE; /********************************************************************************/ void CDomainG::OnTimer(UINT nIDEvent) { LPMYDEFSTRANDHANDLE lpMyDefStrAndHandle=new MYDEFSTRANDHANDLE; //分配 lpMyDefStrAndHandle->glTagMsg=new MyDefStr[DomainName_c]; //分配 lpMyDefStrAndHandle->phThreads=new HANDLE[DomainName_c]; //分配 // 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 <DomainName_c;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(DoDeleteThread,(LPVOID)lpMyDefStrAndHandle,THREAD_PRIORITY_IDLE);//创建一个专门用来释放空间的线程 } else{ delete [] lpMyDefStrAndHandle->glTagMsg; //释放 delete [] lpMyDefStrAndHandle->phThreads; //释放 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<DomainName_c;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(DoDeleteThread,(LPVOID)lpMyDefStrAndHandle,THREAD_PRIORITY_IDLE); } else{ delete [] lpMyDefStrAndHandle->glTagMsg; delete [] lpMyDefStrAndHandle->phThreads; delete lpMyDefStrAndHandle; } } CDialog::OnTimer(nIDEvent); } UINT CDomainG::DoDeleteThread( LPVOID pParam) { LPMYDEFSTRANDHANDLE lpMyDefStrAndHandle=(LPMYDEFSTRANDHANDLE)pParam; WaitForMultipleObjects(lpMyDefStrAndHandle->glTagMsg->pDlg->DomainName_c,lpMyDefStrAndHandle->phThreads,true,INFINITE); //守候OnTimer中创建的所有线程结束 delete [] lpMyDefStrAndHandle->glTagMsg; delete [] lpMyDefStrAndHandle->phThreads; delete lpMyDefStrAndHandle; return 0; }


    DomainName_c过大会出错.和运行时间过长会出错.

    请高手请教.希望能正确和具体的帮我解决.不要丢一两句话.请具体代码好吗!帮我改改.
    100  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 15:46:311楼 得分:0
    DomainName_c 太大会出错这是天经地义的,系统只能容纳有限数量的线程,也只能提供有限数量的内存。DomainName_c 太大了不是内存不够用,就是超过了系统线程上限,不出错才怪呢!

    至于长时间出错的可能原因:
      1 DoDeleteThread  需要等 OnTimer 建立的所有线程都自然结束后才会释放内存。如果其间有至少一个线程死掉而不能正常结束,这片内存就不能释放。 无论你的内存多大,长时间运行后也会无内存可用而出错!

      2 比较 OnTimer 创建线程的速度和线程结束的速度,平均情况下,创建线程的速度那怕略大于线程结束的速度, 长时间运行后也会用尽线程资源或用尽内存而出错!

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 15:55:262楼 得分:0
    MyThread的代码没有给出,MyThread里面要设置DeleteTread中要等待的event德,不晓得设置没,不然这部分代码贴上去。再看看哦! 呵呵!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 16:03:583楼 得分:0
    把分配内存的
    LPMYDEFSTRANDHANDLE lpMyDefStrAndHandle=new MYDEFSTRANDHANDLE; //分配
    lpMyDefStrAndHandle->glTagMsg=new MyDefStr[DomainName_c]; //分配
    lpMyDefStrAndHandle->phThreads=new HANDLE[DomainName_c]; //分配
    放在需要的条件语句内
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 16:04:514楼 得分:0
    提点建议,你可以修改下试试。
              CWinThread* pThread = AfxBeginThread(MyThread,(LPVOID)&lpMyDefStrAndHandle->glTagMsg[i],THREAD_PRIORITY_IDLE);
            lpMyDefStrAndHandle->phThreads[i]=pThread->m_hThread;

    这两句话的意思是把新建线程句柄保存在lpMyDefStrAndHandle->phThreads[i]中,但是你的线程句柄是在for循环中定义的,所以这个句柄不是整个程序期间都有效的,所以在删除线程时可能会出错,而且这种错误不确定的出现。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-05-07 16:05:195楼 得分:0
    你这段程序有严重隐患,涉及思路有问题。timmer是定时执行的,在下一次timmer到来时,上一次timmer创建的线程没有退出,所以资源也没有释放。当domain值过大或者运行时间很长时,由于无数次timmer触发积累了很多没有结束释放的线程及相关资源,必然造成资源耗尽,程序崩溃。结论,你这段代码只能重新设计编写,改不了
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • cnzdgs
    • 等级:
    发表于:2008-05-07 16:47:426楼 得分:0
    WaitForMultipleObjects等待的最大句柄数是64,大于64是会立即返回WAIT_FAILED,这时线程还在运行,你把线程要访问的指针delete掉所以会出问题,这是DomainName_c过大问题的原因。既然你要等待所有线程结束,可以用循环WaitForSingleObject逐一等待。

    运行时间过长会出错要看一下线程的代码。
    修改 删除 举报 引用 回复

    网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
    世纪乐知(北京)网络技术有限公司 版权所有 京 ICP 证 020026 号
    Copyright © 2000-2007, CSDN.NET, All Rights Reserved