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

📄 cgrowablethreadpool.h

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

#ifndef __CGrowableThreadPool_H__
#define __CGrowableThreadPool_H__

#include <CMclGlobal.h>
#include <CMclAutoLock.h>
#include <CMclLinkedLists.h>
#include <CMclThread.h>
#include <CMclCritSec.h>
#include <CMclSemaphore.h>
#include <CMclEvent.h>
#include <CMclWaitableCollection.h>
#include <CMclAutoPtr.h>
#include "CThreadPool.h"

// CLinkedListRemovable
//
// This class provides a Remove() operation in addition to the
// regulare operations provided by CMclLinkedList.  To use
// this class, objects of type T must provide an equality (==)
// operator.
//
template <class T>
class CLinkedListRemovable : public CMclLinkedList<T>
{
    public:
        BOOL Remove( T & rData )
        {
            BOOL fFoundAndRemoved = FALSE;

            CMclAutoLock        Lock(m_cCritSec);
            CMclLinkedListNode *pTargetNode = 0;
            CMclLinkedListNode *pNode = m_MasterNode.m_pNext;
            T                   NodeData;
        
            // Search for a node with matchin data.
            //
            while( !fFoundAndRemoved && (pNode != &m_MasterNode) )
            {
                pNode->GetData(NodeData);

                if( NodeData == rData )
                {
                    // Found it!  Make a note and terminate the
                    // search.
                    //
                    fFoundAndRemoved = TRUE;
                    pTargetNode = pNode;
                }
                else
                {
                    pNode = pNode->m_pNext;
                }
            }

            if( fFoundAndRemoved )
            {
                // Link the node before the target node to the node
                // following the target node.
                //
                pTargetNode->m_pPrev->m_pNext = pTargetNode->m_pNext;
                pTargetNode->m_pNext->m_pPrev = pTargetNode->m_pPrev;

                // Toss the removed node back on the free list of nodes.
                //
                AddToFreeList(pTargetNode);

                // If the list is empty now, reset the NotEmpty event.
                //
                if( m_MasterNode.m_pNext == &m_MasterNode )
                {
                    m_cNotEmpty.Reset();
                }
            }

            return(fFoundAndRemoved);
        }
};

class CGrowableThreadPool : public CThreadPool, private CMclThreadHandler
{
    public:
        CGrowableThreadPool( long lMinThreads, long lMaxThreads, DWORD dwThreadLifetime );
        virtual ~CGrowableThreadPool();

        // CThreadPool implementation.
        //
        virtual BOOL DispatchThread( CMclThreadHandler *pHandler );

    private:
        // CMclThreadHandler implementation.
        //
        virtual unsigned ThreadHandlerProc( void );

    private:
        // CDispatchRecords are enqueued to signal a pending
        // DispatchThread operation that needs to be serviced.
        //
        class CDispatchRecord
        {
            public:
                CDispatchRecord();
                CDispatchRecord( CMclThreadHandler *pThreadHandler );

                unsigned Execute( void );
                int operator == ( const CDispatchRecord& rhs );

            private:
                CMclThreadHandler  *m_pUserThreadHandler;
        };

        // Because threads in this pool all execute the same
        // thread handler in the CGrowableThreadPool class, and
        // because threads may terminate themselves if they
        // sit idle too long in the pool, the thread handler proce
        // needs a way to recover the pointer to the CMclThread
        // object that embodies the thread that is executing.
        // To do this, we maintain a map between thread ids and
        // CMclThread * pointers.
        //
        class CThreadIdToPtrMap
        {
            public:
                CThreadIdToPtrMap( long lMaxThreads );
                ~CThreadIdToPtrMap();

                void        AddThread( DWORD dwThreadId, CMclThread *pThread );
                CMclThread *GetThreadFromId( DWORD dwThreadId );
                void        FreeSlot( DWORD dwThreadId );
                void        FreeSlot( CMclThread *pThread );

            private:
                struct THREADINFO
                {
                    BOOL        fSlotUsed;
                    DWORD       dwThreadId;
                    CMclThread *pThread;
                };

                THREADINFO *m_pThreadIdMap;
                long        m_lMaxThreads;
        };

    private:
        // Thread pool synchronization and management.
        //
        CMclCritSec                         m_csPool;
        CMclEvent                           m_ExitEvent;
        DWORD                               m_dwThreadLifetime;
        CThreadIdToPtrMap                   m_ThreadIdMap;

        // Dispatch queue and thread pool.
        //
        CMclQueue<CDispatchRecord>          m_DispatchQ;
        CMclSemaphore                       m_JobsPending;
        
        long                                m_lMinThreads;  // Numbers of alive threads; not
        long                                m_lMaxThreads;  // counting who's busy and who's
        long                                m_lCurThreads;  // not busy.

        // List of threads in the pool and a semaphore that
        // indicates how many are actually free (idle).
        //
        CLinkedListRemovable<CMclThread *>  m_ThreadsInPool;
        CMclSemaphore                       m_ThreadsFree;
};

#endif // __CGrowableThreadPool_H__

⌨️ 快捷键说明

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