继续多线程问题--我使用CEvent进行多线称同步! 在子线程的 pParentThread->fevetn.SetEvent();//启动父线程继续调度其他子线程 添加断点,清除其它断点执行看看是否执行到这一语句。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 难道子线程的入口都没有进去吗?检查是否死锁了。另外你的 CEvent 对象应该被初始化为 ManualReset 模式的,在 CEvent 的构造中这样做。 dcz(dcz):一定要设置成manualReset模式吗,有什么不同? 应当避免在父线程使用Wait....函数,这样很容易阻塞,失去响应,应当在子线程发送消息....这是我的思路 Great_Bug:那父线程怎么和子线程同步呢 我在编线程时有wait也总是死锁,不管是用WaitForSingleObject等待Event,Thread等等,还是用MsgWaitForMultipleObjects等待设置了m_pMainWnd的Thread,只要设成INFINITE,都会死锁 voidman():照你说,多线程的问题解决不了了阿.不能吧? // MultiThreadMgr.cpp: implementation of the CMultiThreadMgr class.////////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "chkwork.h"#include "MultiThreadMgr.h"#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endif//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////IMPLEMENT_DYNCREATE(CMultiThreadMgr, CWinThread)CMultiThreadMgr::CMultiThreadMgr(){ m_pMainWnd=NULL; m_nThreadCountMax=5;}CMultiThreadMgr::~CMultiThreadMgr(){}BEGIN_MESSAGE_MAP(CMultiThreadMgr, CWinThread) //{{AFX_MSG_MAP(CMultiThreadMgr) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_MSG_MAPEND_MESSAGE_MAP()CMultiThread* CMultiThreadMgr::NewThread(CRuntimeClass* pMultiThreadClass){ ASSERT(pMultiThreadClass!=NULL); ASSERT(pMultiThreadClass->IsDerivedFrom(RUNTIME_CLASS(CMultiThread))); CMultiThread* pMultiThread=(CMultiThread*)pMultiThreadClass->CreateObject(); if (pMultiThread== NULL) return NULL; ASSERT_VALID(pMultiThread); pMultiThread->m_pThreadParams = NULL; m_ptrlstThreadScheduled.AddTail(pMultiThread); // If you want to make the sample more sprightly, set the thread priority here // a little higher. It has been set at idle priority to keep from bogging down // other apps that may also be running. return pMultiThread;}int CMultiThreadMgr::GetActiveThreadCount(){ CMultiThreadCriticalSection mtcs; return m_ptrlstThreadRunning.GetCount();}BOOL CMultiThreadMgr::InitInstance(){ //start all threads ASSERT(m_hThread != NULL); ASSERT(m_pMainWnd!= NULL); CMultiThread* pMultiThread=NULL; POSITION pos=NULL; //start while((!m_ptrlstThreadScheduled.IsEmpty())&& m_ptrlstThreadRunning.GetCount()<m_nThreadCountMax){ pMultiThread= m_ptrlstThreadScheduled.RemoveHead(); pMultiThread->m_pMainWnd=m_pMainWnd; if (!pMultiThread->CreateThread(CREATE_SUSPENDED)){ delete pMultiThread; ::AfxThrowMemoryException(); continue; } m_ptrlstThreadRunning.AddTail(pMultiThread); pMultiThread->ResumeThread(); } while(TRUE){ ::WaitForSingleObject(CMultiThread::m_eventAnotherDead,INFINITE);//wait for some thread ended //check for kill message if(IsKilling()){//is to be killed //delete all Scheduled threads pos=m_ptrlstThreadScheduled.GetHeadPosition(); while(pos){ pMultiThread=m_ptrlstThreadScheduled.GetNext(pos); delete pMultiThread; } m_ptrlstThreadScheduled.RemoveAll(); ////notify kill to running threads pos=m_ptrlstThreadRunning.GetHeadPosition(); while(pos){ pMultiThread=m_ptrlstThreadRunning.GetNext(pos); VERIFY(pMultiThread->m_eventKill.SetEvent()); } //wait for running threads to finish for (int nThreadsLeft = m_ptrlstThreadRunning.GetCount(); nThreadsLeft != 0; ){ WaitForSingleObject(CMultiThread::m_eventAnotherDead, INFINITE); Sleep(nThreadsLeft*2);// 200ms for every 100 threads nThreadsLeft = 0; pos=m_ptrlstThreadRunning.GetHeadPosition(); while(pos){ pMultiThread=m_ptrlstThreadRunning.GetNext(pos); if (!pMultiThread->IsDead()) ++nThreadsLeft; } } // delete all running thread objects while (!m_ptrlstThreadRunning.IsEmpty()) { pMultiThread= m_ptrlstThreadRunning.RemoveHead(); VERIFY(WaitForSingleObject(pMultiThread->m_hThread, INFINITE) == WAIT_OBJECT_0); delete pMultiThread; } if(m_AutoNotifyOnExit) PostMessage(); return FALSE; } else{//run pos=m_ptrlstThreadRunning.GetHeadPosition(); //check dead threads while(pos){ POSITION posCur=pos; pMultiThread=m_ptrlstThreadRunning.GetNext(pos); if (pMultiThread->IsDead()){//dead VERIFY(WaitForSingleObject(pMultiThread->m_hThread, INFINITE) == WAIT_OBJECT_0); delete pMultiThread; m_ptrlstThreadRunning.RemoveAt(posCur); } } //select a thread to start if(m_ptrlstThreadRunning.GetCount()<m_nThreadCountMax){ if(!m_ptrlstThreadScheduled.IsEmpty()){ pMultiThread= m_ptrlstThreadScheduled.RemoveHead(); pMultiThread->m_pMainWnd=m_pMainWnd; if (!pMultiThread->CreateThread(CREATE_SUSPENDED)){ delete pMultiThread; ::AfxThrowMemoryException(); continue; } m_ptrlstThreadRunning.AddTail(pMultiThread); pMultiThread->ResumeThread(); } else{ if(m_ptrlstThreadRunning.IsEmpty()){//no threads left,end if(m_AutoNotifyOnExit) PostMessage(); return FALSE; } } } } } return FALSE;}CMultiThreadMgr* CMultiThreadMgr::Create(CWnd* pMainWnd/*=NULL*/){ CMultiThreadMgr* pMultiThreadMgr=new CMultiThreadMgr; if(pMultiThreadMgr==NULL) ::AfxThrowMemoryException(); if(pMainWnd==NULL) pMultiThreadMgr->m_pMainWnd=::AfxGetMainWnd(); else pMultiThreadMgr->m_pMainWnd=pMainWnd; return pMultiThreadMgr;}// MultiThreadMgr.cpp: implementation of the CMultiThreadMgr class.////////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "chkwork.h"#include "MultiThreadMgr.h"#ifdef _DEBUG#undef THIS_FILEstatic char THIS_FILE[]=__FILE__;#define new DEBUG_NEW#endif//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////IMPLEMENT_DYNCREATE(CMultiThreadMgr, CWinThread)CMultiThreadMgr::CMultiThreadMgr(){ m_pMainWnd=NULL; m_nThreadCountMax=5;}CMultiThreadMgr::~CMultiThreadMgr(){}BEGIN_MESSAGE_MAP(CMultiThreadMgr, CWinThread) //{{AFX_MSG_MAP(CMultiThreadMgr) // NOTE - the ClassWizard will add and remove mapping macros here. //}}AFX_MSG_MAPEND_MESSAGE_MAP()CMultiThread* CMultiThreadMgr::NewThread(CRuntimeClass* pMultiThreadClass){ ASSERT(pMultiThreadClass!=NULL); ASSERT(pMultiThreadClass->IsDerivedFrom(RUNTIME_CLASS(CMultiThread))); CMultiThread* pMultiThread=(CMultiThread*)pMultiThreadClass->CreateObject(); if (pMultiThread== NULL) return NULL; ASSERT_VALID(pMultiThread); pMultiThread->m_pThreadParams = NULL; m_ptrlstThreadScheduled.AddTail(pMultiThread); // If you want to make the sample more sprightly, set the thread priority here // a little higher. It has been set at idle priority to keep from bogging down // other apps that may also be running. return pMultiThread;}int CMultiThreadMgr::GetActiveThreadCount(){ CMultiThreadCriticalSection mtcs; return m_ptrlstThreadRunning.GetCount();}BOOL CMultiThreadMgr::InitInstance(){ //start all threads ASSERT(m_hThread != NULL); ASSERT(m_pMainWnd!= NULL); CMultiThread* pMultiThread=NULL; POSITION pos=NULL; //start while((!m_ptrlstThreadScheduled.IsEmpty())&& m_ptrlstThreadRunning.GetCount()<m_nThreadCountMax){ pMultiThread= m_ptrlstThreadScheduled.RemoveHead(); pMultiThread->m_pMainWnd=m_pMainWnd; if (!pMultiThread->CreateThread(CREATE_SUSPENDED)){ delete pMultiThread; ::AfxThrowMemoryException(); continue; } m_ptrlstThreadRunning.AddTail(pMultiThread); pMultiThread->ResumeThread(); } while(TRUE){ ::WaitForSingleObject(CMultiThread::m_eventAnotherDead,INFINITE);//wait for some thread ended //check for kill message if(IsKilling()){//is to be killed //delete all Scheduled threads pos=m_ptrlstThreadScheduled.GetHeadPosition(); while(pos){ pMultiThread=m_ptrlstThreadScheduled.GetNext(pos); delete pMultiThread; } m_ptrlstThreadScheduled.RemoveAll(); ////notify kill to running threads pos=m_ptrlstThreadRunning.GetHeadPosition(); while(pos){ pMultiThread=m_ptrlstThreadRunning.GetNext(pos); VERIFY(pMultiThread->m_eventKill.SetEvent()); } //wait for running threads to finish for (int nThreadsLeft = m_ptrlstThreadRunning.GetCount(); nThreadsLeft != 0; ){ WaitForSingleObject(CMultiThread::m_eventAnotherDead, INFINITE); Sleep(nThreadsLeft*2);// 200ms for every 100 threads nThreadsLeft = 0; pos=m_ptrlstThreadRunning.GetHeadPosition(); while(pos){ pMultiThread=m_ptrlstThreadRunning.GetNext(pos); if (!pMultiThread->IsDead()) ++nThreadsLeft; } } // delete all running thread objects while (!m_ptrlstThreadRunning.IsEmpty()) { pMultiThread= m_ptrlstThreadRunning.RemoveHead(); VERIFY(WaitForSingleObject(pMultiThread->m_hThread, INFINITE) == WAIT_OBJECT_0); delete pMultiThread; } if(m_AutoNotifyOnExit) PostMessage(); return FALSE; } else{//run pos=m_ptrlstThreadRunning.GetHeadPosition(); //check dead threads while(pos){ POSITION posCur=pos; pMultiThread=m_ptrlstThreadRunning.GetNext(pos); if (pMultiThread->IsDead()){//dead VERIFY(WaitForSingleObject(pMultiThread->m_hThread, INFINITE) == WAIT_OBJECT_0); delete pMultiThread; m_ptrlstThreadRunning.RemoveAt(posCur); } } //select a thread to start if(m_ptrlstThreadRunning.GetCount()<m_nThreadCountMax){ if(!m_ptrlstThreadScheduled.IsEmpty()){ pMultiThread= m_ptrlstThreadScheduled.RemoveHead(); pMultiThread->m_pMainWnd=m_pMainWnd; if (!pMultiThread->CreateThread(CREATE_SUSPENDED)){ delete pMultiThread; ::AfxThrowMemoryException(); continue; } m_ptrlstThreadRunning.AddTail(pMultiThread); pMultiThread->ResumeThread(); } else{ if(m_ptrlstThreadRunning.IsEmpty()){//no threads left,end if(m_AutoNotifyOnExit) PostMessage(); return FALSE; } } } } } return FALSE;}CMultiThreadMgr* CMultiThreadMgr::Create(CWnd* pMainWnd/*=NULL*/){ CMultiThreadMgr* pMultiThreadMgr=new CMultiThreadMgr; if(pMultiThreadMgr==NULL) ::AfxThrowMemoryException(); if(pMainWnd==NULL) pMultiThreadMgr->m_pMainWnd=::AfxGetMainWnd(); else pMultiThreadMgr->m_pMainWnd=pMainWnd; return pMultiThreadMgr;}#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CMultiThreadCEvent CMultiThread::m_eventAnotherDead;IMPLEMENT_DYNCREATE(CMultiThread, CWinThread)CMultiThread::CMultiThread():m_eventKill(FALSE,TRUE),m_eventDead(FALSE,TRUE){ m_AutoNotifyOnExit=TRUE; m_bAutoDelete=FALSE; SetMessage();}CMultiThread::~CMultiThread(){}BOOL CMultiThread::InitInstance(){ // TODO: perform and per-thread initialization here return TRUE;}BEGIN_MESSAGE_MAP(CMultiThread, CWinThread) //{{AFX_MSG_MAP(CMultiThread) //}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CMultiThread message handlersvoid CMultiThread::PostMessage(){ ::PostMessage(::AfxGetMainWnd()->GetSafeHwnd(),m_MSG.message,m_MSG.wParam,m_MSG.lParam);}void CMultiThread::SetMessage(UINT Message,WPARAM wParam/*=0*/,LPARAM lParam/*=0*/){ m_MSG.message=Message;m_MSG.wParam=wParam;m_MSG.lParam=lParam;}CCriticalSection CMultiThreadCriticalSection::m_cs;CMultiThreadCriticalSection::CMultiThreadCriticalSection():m_csLock(&m_cs){ m_csLock.Lock();}CMultiThreadCriticalSection::~CMultiThreadCriticalSection(){ m_csLock.Unlock();}void CMultiThread::Delete(){ // calling the base here won't do anything but it is a good habit CWinThread::Delete(); // acknowledge receipt of kill notification VERIFY(m_eventDead.SetEvent()); VERIFY(m_eventAnotherDead.SetEvent());}void CMultiThread::KillThread(){ // Note: this function is called in the context of other threads, // not the thread itself. // reset the m_hEventKill which signals the thread to shutdown VERIFY(m_eventKill.SetEvent()); // allow thread to run at higher priority during kill process SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL); WaitForSingleObject(m_eventDead, INFINITE); WaitForSingleObject(m_hThread, INFINITE); // now delete CWinThread object since no longer necessary delete this;}BOOL CMultiThread::IsKilling(){ return ::WaitForSingleObject(m_eventKill,0)==WAIT_OBJECT_0;}BOOL CMultiThread::IsDead(){ return ::WaitForSingleObject(m_eventDead,0)==WAIT_OBJECT_0;} jiangsheng(蒋晟):我慢慢研究一下你的代码!谢谢! jiangsheng(蒋晟):http://www.csdn.net/expert/TopicView.asp?id=249632看一下!!! 看了,好像是一样的啊我这个代码是控制同时启动的线程个数的。// MultiThread.h : header file///////////////////////////////////////////////////////////////////////////////// CMultiThread threadclass CMultiThread : public CWinThread{ DECLARE_DYNCREATE(CMultiThread)protected: CMultiThread(); // protected constructor used by dynamic creation// Attributes CEvent m_eventKill;//killing call CEvent m_eventDead;//killedstatic CEvent m_eventAnotherDead;//some thread killed BOOL IsKilling(); BOOL IsDead();protected:// Operationspublic: void KillThread();//kill this thread in another thread virtual void Delete();//overwrite to disable autodelete and notidy killed stateprotected:// Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMultiThread) public: virtual BOOL InitInstance(); //}}AFX_VIRTUAL// Implementationpublic: virtual ~CMultiThread(); // Generated message map functions //{{AFX_MSG(CMultiThread) //}}AFX_MSG // the thread to be stopped and return without terminate this thread DECLARE_MESSAGE_MAP()};/////////////////////////////////////////////////////////////////////////////class CMultiThreadCriticalSection{public: CMultiThreadCriticalSection(); static CCriticalSection m_cs; CSingleLock m_csLock; ~CMultiThreadCriticalSection();};class CMultiThreadMgr : public CMultiThread{public:// Constructor DECLARE_DYNCREATE(CMultiThreadMgr) CMultiThreadMgr(); static CMultiThreadMgr* Create(CWnd* pMainWnd=NULL);//static// Attributes CTypedPtrList<CObList,CMultiThread*> m_ptrlstThreadScheduled; CTypedPtrList<CObList,CMultiThread*> m_ptrlstThreadRunning; int m_nThreadCountMax;// Operationspublic:// Initialization Operations - should be done before InitInstance CMultiThread* NewThread(CRuntimeClass* pMultiThreadClass); int GetActiveThreadCount(); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CBallThread)protected: virtual BOOL InitInstance(); //}}AFX_VIRTUAL// Implementationpublic: virtual ~CMultiThreadMgr();protected: // Generated message map functions //{{AFX_MSG(CMultiThreadMgr) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG DECLARE_MESSAGE_MAP()}; 外部使用: //perform cleaning m_pThreadMgr->KillAllThreads(); //perform cleaning m_pThreadMgr=pDoc->CreateThread(this); while(somecondition){ CReportThread* pReportThread=(CReportThread*)m_pThreadMgr->NewThread(RUNTIME_CLASS(CReportThread)); if(pReportThread){ //set initial parameters DoSomething(pReportThread); } m_pThreadMgr->CreateThread(); 因为父线程有窗口,所以父线程到子线程用Event,子线程到父线程用Message,很方便的,而且不会阻塞 在没个线程中加一个AFXMESSAGEBOX,看看那个没有运行必要的时候,不要用数组,直接用几个AFXBEGINTHREAD试试。如果DOWNLOAD没有运行,就是没有CEVENT设置不对如果都没有运行,就是有冲突,那用全局变量试试 masterjames(james):我一定试试! BUG in BOOL CMultiThreadMgr::InitInstance()add if(m_ptrlstThreadScheduled.IsEmpty()) return FALSE;at the beginning of this function. 老大,把你afxbeginthread的详细参数post出来,然后,检查一下resumethread的返回值,看看是否成功,如果是fail,就用getlasterror查查errorcode。看看原因。你的思路应该没错。我写多线程,也在主线程中用waitforsingleobject,等待event,让他等待子线程的结束,用的好好的呢。 求助 谁帮忙搞一个mfc对话框的中国象棋给我谢谢啦! 请问关于report类型的列表控件显示问题 怎样判断是否一个窗口是否属于某个进程呢? 高手看看在线人数为什么不能显示了?(有源码下载) 求教:vc中如何将文件转换为二进制数据 (100分求)用户权限分配可以通过编程实现吗 CFileDialog名字固定问题 急!!! 问一个自绘listbox窗口的问题 怎样做像设置控件属性时的对话框? 一个简单的游戏算法?谁知道? 请讲解一下钩子 谁有数字时钟的控件?
一定要设置成manualReset模式吗,有什么不同?
这是我的思路
那父线程怎么和子线程同步呢
等待Event,Thread等等,还是用MsgWaitForMultipleObjects等待设置了m_pMainWnd的Thread,只要设成INFINITE,都会死锁
照你说,多线程的问题解决不了了阿.
不能吧?
//
//////////////////////////////////////////////////////////////////////#include "stdafx.h"
#include "chkwork.h"
#include "MultiThreadMgr.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(CMultiThreadMgr, CWinThread)
CMultiThreadMgr::CMultiThreadMgr()
{
m_pMainWnd=NULL;
m_nThreadCountMax=5;
}CMultiThreadMgr::~CMultiThreadMgr()
{}
BEGIN_MESSAGE_MAP(CMultiThreadMgr, CWinThread)
//{{AFX_MSG_MAP(CMultiThreadMgr)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()CMultiThread* CMultiThreadMgr::NewThread(CRuntimeClass* pMultiThreadClass)
{
ASSERT(pMultiThreadClass!=NULL);
ASSERT(pMultiThreadClass->IsDerivedFrom(RUNTIME_CLASS(CMultiThread)));
CMultiThread* pMultiThread=(CMultiThread*)pMultiThreadClass->CreateObject();
if (pMultiThread== NULL)
return NULL;
ASSERT_VALID(pMultiThread);
pMultiThread->m_pThreadParams = NULL;
m_ptrlstThreadScheduled.AddTail(pMultiThread);
// If you want to make the sample more sprightly, set the thread priority here
// a little higher. It has been set at idle priority to keep from bogging down
// other apps that may also be running.
return pMultiThread;
}int CMultiThreadMgr::GetActiveThreadCount()
{
CMultiThreadCriticalSection mtcs;
return m_ptrlstThreadRunning.GetCount();
}BOOL CMultiThreadMgr::InitInstance()
{
//start all threads
ASSERT(m_hThread != NULL);
ASSERT(m_pMainWnd!= NULL);
CMultiThread* pMultiThread=NULL;
POSITION pos=NULL;
//start
while((!m_ptrlstThreadScheduled.IsEmpty())&& m_ptrlstThreadRunning.GetCount()<m_nThreadCountMax){
pMultiThread= m_ptrlstThreadScheduled.RemoveHead();
pMultiThread->m_pMainWnd=m_pMainWnd;
if (!pMultiThread->CreateThread(CREATE_SUSPENDED)){
delete pMultiThread;
::AfxThrowMemoryException();
continue;
}
m_ptrlstThreadRunning.AddTail(pMultiThread);
pMultiThread->ResumeThread();
}
while(TRUE){
::WaitForSingleObject(CMultiThread::m_eventAnotherDead,INFINITE);//wait for some thread ended
//check for kill message
if(IsKilling()){//is to be killed
//delete all Scheduled threads
pos=m_ptrlstThreadScheduled.GetHeadPosition();
while(pos){
pMultiThread=m_ptrlstThreadScheduled.GetNext(pos);
delete pMultiThread;
}
m_ptrlstThreadScheduled.RemoveAll();
////notify kill to running threads
pos=m_ptrlstThreadRunning.GetHeadPosition();
while(pos){
pMultiThread=m_ptrlstThreadRunning.GetNext(pos);
VERIFY(pMultiThread->m_eventKill.SetEvent());
}
//wait for running threads to finish
for (int nThreadsLeft = m_ptrlstThreadRunning.GetCount(); nThreadsLeft != 0; ){
WaitForSingleObject(CMultiThread::m_eventAnotherDead, INFINITE);
Sleep(nThreadsLeft*2);// 200ms for every 100 threads
nThreadsLeft = 0;
pos=m_ptrlstThreadRunning.GetHeadPosition();
while(pos){
pMultiThread=m_ptrlstThreadRunning.GetNext(pos);
if (!pMultiThread->IsDead())
++nThreadsLeft;
}
}
// delete all running thread objects
while (!m_ptrlstThreadRunning.IsEmpty())
{
pMultiThread= m_ptrlstThreadRunning.RemoveHead();
VERIFY(WaitForSingleObject(pMultiThread->m_hThread, INFINITE) == WAIT_OBJECT_0);
delete pMultiThread;
}
if(m_AutoNotifyOnExit)
PostMessage();
return FALSE;
}
else{//run
pos=m_ptrlstThreadRunning.GetHeadPosition();
//check dead threads
while(pos){
POSITION posCur=pos;
pMultiThread=m_ptrlstThreadRunning.GetNext(pos);
if (pMultiThread->IsDead()){//dead
VERIFY(WaitForSingleObject(pMultiThread->m_hThread, INFINITE) == WAIT_OBJECT_0);
delete pMultiThread;
m_ptrlstThreadRunning.RemoveAt(posCur);
}
}
//select a thread to start
if(m_ptrlstThreadRunning.GetCount()<m_nThreadCountMax){
if(!m_ptrlstThreadScheduled.IsEmpty()){
pMultiThread= m_ptrlstThreadScheduled.RemoveHead();
pMultiThread->m_pMainWnd=m_pMainWnd;
if (!pMultiThread->CreateThread(CREATE_SUSPENDED)){
delete pMultiThread;
::AfxThrowMemoryException();
continue;
}
m_ptrlstThreadRunning.AddTail(pMultiThread);
pMultiThread->ResumeThread();
}
else{
if(m_ptrlstThreadRunning.IsEmpty()){//no threads left,end
if(m_AutoNotifyOnExit)
PostMessage();
return FALSE;
}
}
}
}
}
return FALSE;
}CMultiThreadMgr* CMultiThreadMgr::Create(CWnd* pMainWnd/*=NULL*/)
{
CMultiThreadMgr* pMultiThreadMgr=new CMultiThreadMgr;
if(pMultiThreadMgr==NULL)
::AfxThrowMemoryException();
if(pMainWnd==NULL)
pMultiThreadMgr->m_pMainWnd=::AfxGetMainWnd();
else
pMultiThreadMgr->m_pMainWnd=pMainWnd;
return pMultiThreadMgr;
}
// MultiThreadMgr.cpp: implementation of the CMultiThreadMgr class.
//
//////////////////////////////////////////////////////////////////////#include "stdafx.h"
#include "chkwork.h"
#include "MultiThreadMgr.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNCREATE(CMultiThreadMgr, CWinThread)
CMultiThreadMgr::CMultiThreadMgr()
{
m_pMainWnd=NULL;
m_nThreadCountMax=5;
}CMultiThreadMgr::~CMultiThreadMgr()
{}
BEGIN_MESSAGE_MAP(CMultiThreadMgr, CWinThread)
//{{AFX_MSG_MAP(CMultiThreadMgr)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()CMultiThread* CMultiThreadMgr::NewThread(CRuntimeClass* pMultiThreadClass)
{
ASSERT(pMultiThreadClass!=NULL);
ASSERT(pMultiThreadClass->IsDerivedFrom(RUNTIME_CLASS(CMultiThread)));
CMultiThread* pMultiThread=(CMultiThread*)pMultiThreadClass->CreateObject();
if (pMultiThread== NULL)
return NULL;
ASSERT_VALID(pMultiThread);
pMultiThread->m_pThreadParams = NULL;
m_ptrlstThreadScheduled.AddTail(pMultiThread);
// If you want to make the sample more sprightly, set the thread priority here
// a little higher. It has been set at idle priority to keep from bogging down
// other apps that may also be running.
return pMultiThread;
}int CMultiThreadMgr::GetActiveThreadCount()
{
CMultiThreadCriticalSection mtcs;
return m_ptrlstThreadRunning.GetCount();
}BOOL CMultiThreadMgr::InitInstance()
{
//start all threads
ASSERT(m_hThread != NULL);
ASSERT(m_pMainWnd!= NULL);
CMultiThread* pMultiThread=NULL;
POSITION pos=NULL;
//start
while((!m_ptrlstThreadScheduled.IsEmpty())&& m_ptrlstThreadRunning.GetCount()<m_nThreadCountMax){
pMultiThread= m_ptrlstThreadScheduled.RemoveHead();
pMultiThread->m_pMainWnd=m_pMainWnd;
if (!pMultiThread->CreateThread(CREATE_SUSPENDED)){
delete pMultiThread;
::AfxThrowMemoryException();
continue;
}
m_ptrlstThreadRunning.AddTail(pMultiThread);
pMultiThread->ResumeThread();
}
while(TRUE){
::WaitForSingleObject(CMultiThread::m_eventAnotherDead,INFINITE);//wait for some thread ended
//check for kill message
if(IsKilling()){//is to be killed
//delete all Scheduled threads
pos=m_ptrlstThreadScheduled.GetHeadPosition();
while(pos){
pMultiThread=m_ptrlstThreadScheduled.GetNext(pos);
delete pMultiThread;
}
m_ptrlstThreadScheduled.RemoveAll();
////notify kill to running threads
pos=m_ptrlstThreadRunning.GetHeadPosition();
while(pos){
pMultiThread=m_ptrlstThreadRunning.GetNext(pos);
VERIFY(pMultiThread->m_eventKill.SetEvent());
}
//wait for running threads to finish
for (int nThreadsLeft = m_ptrlstThreadRunning.GetCount(); nThreadsLeft != 0; ){
WaitForSingleObject(CMultiThread::m_eventAnotherDead, INFINITE);
Sleep(nThreadsLeft*2);// 200ms for every 100 threads
nThreadsLeft = 0;
pos=m_ptrlstThreadRunning.GetHeadPosition();
while(pos){
pMultiThread=m_ptrlstThreadRunning.GetNext(pos);
if (!pMultiThread->IsDead())
++nThreadsLeft;
}
}
// delete all running thread objects
while (!m_ptrlstThreadRunning.IsEmpty())
{
pMultiThread= m_ptrlstThreadRunning.RemoveHead();
VERIFY(WaitForSingleObject(pMultiThread->m_hThread, INFINITE) == WAIT_OBJECT_0);
delete pMultiThread;
}
if(m_AutoNotifyOnExit)
PostMessage();
return FALSE;
}
else{//run
pos=m_ptrlstThreadRunning.GetHeadPosition();
//check dead threads
while(pos){
POSITION posCur=pos;
pMultiThread=m_ptrlstThreadRunning.GetNext(pos);
if (pMultiThread->IsDead()){//dead
VERIFY(WaitForSingleObject(pMultiThread->m_hThread, INFINITE) == WAIT_OBJECT_0);
delete pMultiThread;
m_ptrlstThreadRunning.RemoveAt(posCur);
}
}
//select a thread to start
if(m_ptrlstThreadRunning.GetCount()<m_nThreadCountMax){
if(!m_ptrlstThreadScheduled.IsEmpty()){
pMultiThread= m_ptrlstThreadScheduled.RemoveHead();
pMultiThread->m_pMainWnd=m_pMainWnd;
if (!pMultiThread->CreateThread(CREATE_SUSPENDED)){
delete pMultiThread;
::AfxThrowMemoryException();
continue;
}
m_ptrlstThreadRunning.AddTail(pMultiThread);
pMultiThread->ResumeThread();
}
else{
if(m_ptrlstThreadRunning.IsEmpty()){//no threads left,end
if(m_AutoNotifyOnExit)
PostMessage();
return FALSE;
}
}
}
}
}
return FALSE;
}CMultiThreadMgr* CMultiThreadMgr::Create(CWnd* pMainWnd/*=NULL*/)
{
CMultiThreadMgr* pMultiThreadMgr=new CMultiThreadMgr;
if(pMultiThreadMgr==NULL)
::AfxThrowMemoryException();
if(pMainWnd==NULL)
pMultiThreadMgr->m_pMainWnd=::AfxGetMainWnd();
else
pMultiThreadMgr->m_pMainWnd=pMainWnd;
return pMultiThreadMgr;
}
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif/////////////////////////////////////////////////////////////////////////////
// CMultiThread
CEvent CMultiThread::m_eventAnotherDead;
IMPLEMENT_DYNCREATE(CMultiThread, CWinThread)
CMultiThread::CMultiThread()
:m_eventKill(FALSE,TRUE)
,m_eventDead(FALSE,TRUE)
{
m_AutoNotifyOnExit=TRUE;
m_bAutoDelete=FALSE;
SetMessage();
}CMultiThread::~CMultiThread()
{
}BOOL CMultiThread::InitInstance()
{
// TODO: perform and per-thread initialization here
return TRUE;
}BEGIN_MESSAGE_MAP(CMultiThread, CWinThread)
//{{AFX_MSG_MAP(CMultiThread)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
// CMultiThread message handlersvoid CMultiThread::PostMessage()
{
::PostMessage(::AfxGetMainWnd()->GetSafeHwnd(),m_MSG.message,m_MSG.wParam,m_MSG.lParam);
}void CMultiThread::SetMessage(UINT Message,WPARAM wParam/*=0*/,LPARAM lParam/*=0*/)
{
m_MSG.message=Message;m_MSG.wParam=wParam;m_MSG.lParam=lParam;
}CCriticalSection CMultiThreadCriticalSection::m_cs;
CMultiThreadCriticalSection::CMultiThreadCriticalSection()
:m_csLock(&m_cs)
{
m_csLock.Lock();
}CMultiThreadCriticalSection::~CMultiThreadCriticalSection()
{
m_csLock.Unlock();
}
void CMultiThread::Delete()
{
// calling the base here won't do anything but it is a good habit
CWinThread::Delete();
// acknowledge receipt of kill notification
VERIFY(m_eventDead.SetEvent());
VERIFY(m_eventAnotherDead.SetEvent());
}void CMultiThread::KillThread()
{
// Note: this function is called in the context of other threads,
// not the thread itself.
// reset the m_hEventKill which signals the thread to shutdown
VERIFY(m_eventKill.SetEvent());
// allow thread to run at higher priority during kill process
SetThreadPriority(THREAD_PRIORITY_ABOVE_NORMAL);
WaitForSingleObject(m_eventDead, INFINITE);
WaitForSingleObject(m_hThread, INFINITE);
// now delete CWinThread object since no longer necessary
delete this;
}BOOL CMultiThread::IsKilling()
{
return ::WaitForSingleObject(m_eventKill,0)==WAIT_OBJECT_0;
}BOOL CMultiThread::IsDead()
{
return ::WaitForSingleObject(m_eventDead,0)==WAIT_OBJECT_0;
}
我慢慢研究一下你的代码!谢谢!
http://www.csdn.net/expert/TopicView.asp?id=249632
看一下!!!
我这个代码是控制同时启动的线程个数的。
// MultiThread.h : header file
///////////////////////////////////////////////////////////////////////////////
// CMultiThread thread
class CMultiThread : public CWinThread
{
DECLARE_DYNCREATE(CMultiThread)
protected:
CMultiThread(); // protected constructor used by dynamic creation
// Attributes
CEvent m_eventKill;//killing call
CEvent m_eventDead;//killed
static CEvent m_eventAnotherDead;//some thread killed
BOOL IsKilling();
BOOL IsDead();
protected:// Operations
public:
void KillThread();//kill this thread in another thread
virtual void Delete();//overwrite to disable autodelete and notidy killed state
protected:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMultiThread)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CMultiThread();
// Generated message map functions
//{{AFX_MSG(CMultiThread)
//}}AFX_MSG
// the thread to be stopped and return without terminate this thread
DECLARE_MESSAGE_MAP()
};/////////////////////////////////////////////////////////////////////////////
class CMultiThreadCriticalSection{
public:
CMultiThreadCriticalSection();
static CCriticalSection m_cs;
CSingleLock m_csLock;
~CMultiThreadCriticalSection();
};class CMultiThreadMgr : public CMultiThread
{
public:
// Constructor
DECLARE_DYNCREATE(CMultiThreadMgr)
CMultiThreadMgr();
static CMultiThreadMgr* Create(CWnd* pMainWnd=NULL);//static
// Attributes
CTypedPtrList<CObList,CMultiThread*> m_ptrlstThreadScheduled;
CTypedPtrList<CObList,CMultiThread*> m_ptrlstThreadRunning;
int m_nThreadCountMax;
// Operations
public:
// Initialization Operations - should be done before InitInstance
CMultiThread* NewThread(CRuntimeClass* pMultiThreadClass);
int GetActiveThreadCount();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CBallThread)
protected:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CMultiThreadMgr();
protected:
// Generated message map functions
//{{AFX_MSG(CMultiThreadMgr)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//perform cleaning
m_pThreadMgr->KillAllThreads();
//perform cleaning
m_pThreadMgr=pDoc->CreateThread(this);
while(somecondition){
CReportThread* pReportThread=(CReportThread*)m_pThreadMgr->NewThread(RUNTIME_CLASS(CReportThread));
if(pReportThread){
//set initial parameters
DoSomething(pReportThread);
}
m_pThreadMgr->CreateThread();
必要的时候,不要用数组,直接用几个AFXBEGINTHREAD
试试。如果DOWNLOAD没有运行,就是没有CEVENT设置不对
如果都没有运行,就是有冲突,那用全局变量试试
我一定试试!
add
if(m_ptrlstThreadScheduled.IsEmpty())
return FALSE;
at the beginning of this function.