在子线程的 
pParentThread->fevetn.SetEvent();//启动父线程继续调度其他子线程 
添加断点,清除其它断点执行看看是否执行到这一语句。

解决方案 »

  1.   

    难道子线程的入口都没有进去吗?检查是否死锁了。另外你的 CEvent 对象应该被初始化为 ManualReset 模式的,在 CEvent 的构造中这样做。
      

  2.   

    dcz(dcz):
    一定要设置成manualReset模式吗,有什么不同?
      

  3.   

    应当避免在父线程使用Wait....函数,这样很容易阻塞,失去响应,应当在子线程发送消息....
    这是我的思路
      

  4.   

    Great_Bug:
    那父线程怎么和子线程同步呢
      

  5.   

    我在编线程时有wait也总是死锁,不管是用WaitForSingleObject
    等待Event,Thread等等,还是用MsgWaitForMultipleObjects等待设置了m_pMainWnd的Thread,只要设成INFINITE,都会死锁
      

  6.   

    voidman():
    照你说,多线程的问题解决不了了阿.
    不能吧?
      

  7.   

    // 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;
    }
    // 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;
    }
      

  8.   

    jiangsheng(蒋晟):
    我慢慢研究一下你的代码!谢谢!
      

  9.   

    jiangsheng(蒋晟):
    http://www.csdn.net/expert/TopicView.asp?id=249632
    看一下!!!
      

  10.   

    看了,好像是一样的啊
    我这个代码是控制同时启动的线程个数的。
    // 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()
    };
      

  11.   

    外部使用:
    //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();
      

  12.   

    因为父线程有窗口,所以父线程到子线程用Event,子线程到父线程用Message,很方便的,而且不会阻塞
      

  13.   

    在没个线程中加一个AFXMESSAGEBOX,看看那个没有运行
    必要的时候,不要用数组,直接用几个AFXBEGINTHREAD
    试试。如果DOWNLOAD没有运行,就是没有CEVENT设置不对
    如果都没有运行,就是有冲突,那用全局变量试试
      

  14.   

    masterjames(james):
    我一定试试!
      

  15.   

    BUG in BOOL CMultiThreadMgr::InitInstance()
    add 
    if(m_ptrlstThreadScheduled.IsEmpty())
        return FALSE;
    at the beginning of this function.
      

  16.   

    老大,把你afxbeginthread的详细参数post出来,然后,检查一下resumethread的返回值,看看是否成功,如果是fail,就用getlasterror查查errorcode。看看原因。你的思路应该没错。我写多线程,也在主线程中用waitforsingleobject,等待event,让他等待子线程的结束,用的好好的呢。