⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sehmgr.cpp

📁 window下的多线程编程参考书。值得一读
💻 CPP
字号:
//
// FILE: SEHMgr.cpp
//
// Copyright (c) 1997 by Aaron Michael Cohen and Mike Woodring
//
/////////////////////////////////////////////////////////////////////////

#include <windows.h>
#include <stdio.h>
#include <CGuardedThreadHandler.h>
#include <CMclWaitableCollection.h>
#include "SynchExceptionMgr.h"
#include "AsynchExceptionMgr.h"

// USE_SYNCH_EXCEPTION_MGR is used to control whether or not this
// application uses the synchronous form of the exception manager
// (CSynchronousExceptionManager) or the asynchronous form
// (CAsynchronousExceptionManager).  Because both are derived from
// the CExceptionManager base class, the remainder of this application
// doesn't differentiate between them.
//
#define USE_SYNCH_EXCEPTION_MGR 1   // 1 => Use CSynchronousExceptionManager
                                    // 0 => Use CAsynchronousExceptionManager

#if USE_SYNCH_EXCEPTION_MGR
CSynchronousExceptionManager    gExceptMgr;
#else
CAsynchronousExceptionManager   gExceptMgr;
#endif

// CWorkerThreadHandler
//
// Defines a worker thread that registers itself with an exception manager
// object when the thread starts, and notifies the exception manager object
// whenever an exception that it can't handle occurs in this thread.
//
class CWorkerThreadHandler : public CGuardedThreadHandler, public CExceptionHandler
{
    public:
        // Class constructor.
        CWorkerThreadHandler( BOOL fBlowUp, CExceptionManager *pEM );

        // CGuardedThreadHandler overrides.
        //
        virtual unsigned GuardedThreadHandlerProc( void );
        virtual unsigned TerminationHandler( DWORD dwExceptionCode );

        // CExceptionHandler override.  This will be called if an exception
        // occurs anywhere else in the program so that we can clean up before
        // the program exits.
        //
        virtual void OnException
        (
            CExceptionHandler::NOTIFICATION_CONTEXT Context,
            DWORD                                   dwExceptionCode
        );
    
    private:
        CExceptionManager  *m_pEM;
        BOOL                m_fBlowUp;
};

// CWorkerThreadHandler implementation.
//
CWorkerThreadHandler::CWorkerThreadHandler( BOOL fBlowUp, CExceptionManager *pEM )
    : m_pEM(pEM),
      m_fBlowUp(fBlowUp)
{
}

unsigned CWorkerThreadHandler::GuardedThreadHandlerProc( void )
{
    // Register with the exception manager.
    //
    m_pEM->RegisterHandler(this);

    printf(
        "[tid 0x%08lx] Worker thread has started (m_fBlowUp == %d).\n",
        GetCurrentThreadId(),
        m_fBlowUp
    );

    for( int i = 0; i < 3; i++ )
    {
        printf(
            "[tid 0x%08lx] Worker about to sleep...\n",
            GetCurrentThreadId()
        );

        Sleep(4000);

        if( (i == 1) && m_fBlowUp )
        {
            printf(
                "[tid 0x%08lx] Worker about to blow up (handler = 0x%x).\n",
                GetCurrentThreadId(),
                (CExceptionHandler *)this
            );

            *((PBYTE)0) = '!';
        }

        printf(
            "[tid 0x%08lx] Worker done sleeping.\n",
            GetCurrentThreadId()
        );
    }

    printf(
        "[tid 0x%08lx] Worker thread exiting thread proc normally.\n",
        GetCurrentThreadId()
    );

    // Unregister with the exception manager just before allowing
    // this thread to exit.
    //
    m_pEM->UnregisterHandler(this);

    return(0);
}

unsigned CWorkerThreadHandler::TerminationHandler( DWORD dwExceptionCode )
{
    printf(
        "[tid 0x%08lx] Worker termination handler (0x%x) running, exception = 0x%x\n",
        GetCurrentThreadId(),
        (CExceptionHandler *)this,
        dwExceptionCode
    );

    // Notify other threads that we're about to exit the process.
    //
    m_pEM->UnregisterHandler(this);
    m_pEM->NotifyException(dwExceptionCode);

    ExitProcess(0xffffffff);
    
    return(0);
}

void CWorkerThreadHandler::OnException
(
    CExceptionHandler::NOTIFICATION_CONTEXT Context,
    DWORD                                   dwExceptionCode
)
{
    printf(
        "[tid 0x%08lx] Worker handler 0x%x OnException(%s exception = 0x%x)\n",
        GetCurrentThreadId(),
        (CExceptionHandler *)this,
        (Context == CExceptionHandler::THREAD_EXCEPTION ? "thread" : "unhandled"),
        dwExceptionCode
    );
}

// Program implementation.
//
void main( void )
{
    CWorkerThreadHandler    WorkerHandler1(FALSE, &gExceptMgr);     // This thread won't fault.
    CMclThread              WorkerThread1(&WorkerHandler1);

    CWorkerThreadHandler    WorkerHandler2(TRUE, &gExceptMgr);      // This thread will fault out.
    CMclThread              WorkerThread2(&WorkerHandler2);

    CWorkerThreadHandler    WorkerHandler3(FALSE, &gExceptMgr);     // This thread won't fault.
    CMclThread              WorkerThread3(&WorkerHandler3);

    #if USE_SYNCH_EXCEPTION_MGR
        printf(
            "[tid 0x%08lx] Synchronous exception manager is being used.\n",
            GetCurrentThreadId()
        ); 
    #else
        printf(
            "[tid 0x%08lx] Asynchronous exception manager is being used.\n",
            GetCurrentThreadId()
        );
    #endif

    printf(
        "[tid 0x%08lx] Waiting for worker threads to exit...\n",
        GetCurrentThreadId()
    );
    
    // Now that the three worker threads are running, wait for
    // them to exit.
    //
    CMclWaitableCollection  WaitSet;

    WaitSet.AddObject(WorkerThread1);
    WaitSet.AddObject(WorkerThread2);
    WaitSet.AddObject(WorkerThread3);
    
    WaitSet.Wait(TRUE, INFINITE);
    
    printf(
        "[tid 0x%08lx] Done waiting for workers to exit.\n",
        GetCurrentThreadId()
    );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -