主要是多線程的互斥 文件 的查找
多線程互斥的框架
//線程函數  
UINT FinderEntry(LPVOID lpParam)  
{  
    //CRapidFinder通過參數傳遞進來   
    CRapidFinder* pFinder = (CRapidFinder*)lpParam;  
    CDirectoryNode* pNode = NULL;  
    BOOL bActive = TRUE; //bActive為TRUE,表示當前線程激活  
    //循環處理m_listDir列表中的目錄  
    while (1)  
    {  
        //從列表中取出一個目錄  
        ::EnterCriticalSection(&pFinder->m_cs);  
        if (pFinder->m_listDir.IsEmpty()) //目錄列表為空,當前線程不激活,所以bAactive=FALSE  
        {  
            bActive = FALSE;  
        }  
        else  
        {  
            pNode = pFinder->m_listDir.GetHead(); //得到一個目錄  
            pFinder->m_listDir.Remove(pNode);    //從目錄列表中移除  
        }  
        ::LeaveCriticalSection(&pFinder->m_cs);  
        //如果停止當前線程  
        if (bActive == FALSE)  
        {  
            //停止當前線程  
            //線程數--  
            pFinder->m_nThreadCount--;  
              
            //如果當前活動線程數為0,跳出,結束  
            if (pFinder->m_nThreadCount == 0)  
            {  
                ::LeaveCriticalSection(&pFinder->m_cs);  
                break;  
            }  
            ::LeaveCriticalSection(&pFinder->m_cs);  
            //當前活動線程數不為0,等待其他線程向目錄列表中加目錄  
            ::ResetEvent(pFinder->m_hDirEvent);  
            ::WaitForSingleObject(pFinder->m_hDirEvent, INFINITE);  
  
            //運行到這,就說明其他線程喚醒了本線程  
              
            pFinder->m_nThreadCount++; //激活了自己的線程,線程數++  
              
            bActive = TRUE; //當前線程活了  
            continue; //跳到while,  
        }  
        //從目錄列表中成功取得了目錄  
<span style="white-space:pre">      </span>......................  
          
        //if (pNode)  
        //{  
        //  delete pNode;  
        //  pNode = NULL;  
        //}  
  
  
    }//end while  
  
    //促使一個搜索線程從WaitForSingleObject返回,并退出循環  
    ::SetEvent(pFinder->m_hDirEvent);  
  
    //判斷此線程是否是最后一個結束循環的線程,如果是就通知主線程  
    if (::WaitForSingleObject(pFinder->m_hDirEvent,0) != WAIT_TIMEOUT)  
    {  
        ::SetEvent(pFinder->m_hExitEvent);  
    }  
    return 1;  
}
 查找文件 的框架:
//從目錄列表中成功取得了目錄  
WIN32_FIND_DATA fileData;  
HANDLE hFindFile;  
//生成正確的查找字符串  
if (pNode->szDir[strlen(pNode->szDir)-1] != '//')  
{  
    strcat(pNode->szDir,"http://");  
}  
strcat(pNode->szDir, "*.*");  
//查找文件的框架  
hFindFile = ::FindFirstFile(pNode->szDir, &fileData);  
if (hFindFile != INVALID_HANDLE_VALUE )  
{  
    do   
    {  
 //如果是當前目錄,跳過  
 if (fileData.cFileName[0] == '.')  
 {  
     continue;  
 }  
 //如果是目錄  
 if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)  
 {  
     //將當前目錄加入到目錄列表  
     。。。。。。  
     //使一個線程從非活動狀態變成活動狀態  
     ::SetEvent(pFinder->m_hDirEvent);  
 }  
 else //如果是文件  
 {  
     。。。。。。。。。。。。。  
 }  
    } while (::FindNextFile(hFindFile, &fileData));  
}
 所有代碼main.cpp:
#include "RapidFinder.h"  
#include <stddef.h>  
#include <stdio.h>  
#include <process.h>  
  
//m_nMaxThread 是const int類型,只能通過這種方式初始化  
CRapidFinder::CRapidFinder(int nMaxThread):m_nMaxThread(nMaxThread)  
{  
    m_nResultCount = 0;  
    m_nThreadCount = 0;  
    m_listDir.Construct(offsetof(CDirectoryNode, pNext));  //offsetof在stddef.h頭文件中  
    ::InitializeCriticalSection(&m_cs);  
    m_szMatchName[0] = '/0';  
    m_hDirEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);  
    m_hExitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);  
  
}  
  
CRapidFinder::~CRapidFinder()  
{  
    ::DeleteCriticalSection(&m_cs);  
    ::CloseHandle(m_hDirEvent);  
    ::CloseHandle(m_hExitEvent);  
}  
  
BOOL    CRapidFinder::CheckFile(LPCTSTR lpszFileName)  
{  
    //定義兩個字符串  
    char string[MAX_PATH];  
    char strSearch[MAX_PATH];  
    strcpy(string, lpszFileName);  
    strcpy(strSearch, m_szMatchName);  
  
    //將字符串大寫  
    _strupr(string);  
    _strupr(strSearch);  
  
    //比較string中是否含有strSearch  
    if (strstr(string, strSearch) != NULL)  
    {  
        return TRUE;  
    }  
    return FALSE;  
}
  
//線程函數  
UINT FinderEntry(LPVOID lpParam)  
{  
    //CRapidFinder通過參數傳遞進來   
    CRapidFinder* pFinder = (CRapidFinder*)lpParam;  
    CDirectoryNode* pNode = NULL;  
    BOOL bActive = TRUE; //bActive為TRUE,表示當前線程激活  
    //循環處理m_listDir列表中的目錄  
    while (1)  
    {  
        //從列表中取出一個目錄  
        ::EnterCriticalSection(&pFinder->m_cs);  
        if (pFinder->m_listDir.IsEmpty()) //目錄列表為空,當前線程不激活,所以bAactive=FALSE  
        {  
            bActive = FALSE;  
        }  
        else  
        {  
            pNode = pFinder->m_listDir.GetHead(); //得到一個目錄  
            pFinder->m_listDir.Remove(pNode);    //從目錄列表中移除  
        }  
        ::LeaveCriticalSection(&pFinder->m_cs);  
        //如果停止當前線程  
        if (bActive == FALSE)  
        {  
            //停止當前線程  
            ::EnterCriticalSection(&pFinder->m_cs);  
            pFinder->m_nThreadCount--;  
              
            //如果當前活動線程數為0,跳出,結束  
            if (pFinder->m_nThreadCount == 0)  
            {  
                ::LeaveCriticalSection(&pFinder->m_cs);  
                break;  
            }  
            ::LeaveCriticalSection(&pFinder->m_cs);  
            //當前活動線程數不為0,等待其他線程向目錄列表中加目錄  
            ::ResetEvent(pFinder->m_hDirEvent);  
            ::WaitForSingleObject(pFinder->m_hDirEvent, INFINITE);  
  
            //運行到這,就說明其他線程向目錄列表中加入了新的目錄  
            ::EnterCriticalSection(&pFinder->m_cs);  
            pFinder->m_nThreadCount++; //激活了自己的線程,線程數++  
            ::LeaveCriticalSection(&pFinder->m_cs);  
            bActive = TRUE; //目錄不再為空  
            continue; //跳到while,重新在目錄列表中取目錄  
        }  
        //從目錄列表中成功取得了目錄  
        WIN32_FIND_DATA fileData;  
        HANDLE hFindFile;  
        //生成正確的查找字符串  
        if (pNode->szDir[strlen(pNode->szDir)-1] != '//')  
        {  
            strcat(pNode->szDir,"http://");  
        }  
        strcat(pNode->szDir, "*.*");  
        //查找文件的框架  
        hFindFile = ::FindFirstFile(pNode->szDir, &fileData);  
        if (hFindFile != INVALID_HANDLE_VALUE )  
        {  
            do   
            {  
                //如果是當前目錄,跳過  
                if (fileData.cFileName[0] == '.')  
                {  
                    continue;  
                }  
                //如果是目錄  
                if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)  
                {  
                    //將當前目錄加入到目錄列表  
                    CDirectoryNode* p = new CDirectoryNode;  
                    strncpy(p->szDir, pNode->szDir, strlen(pNode->szDir)-3); //將pNode后面的*.*三位去掉  
                    strcat(p->szDir, fileData.cFileName);  
                    ::EnterCriticalSection(&pFinder->m_cs);  
                    pFinder->m_listDir.AddHead(p);  
                    ::LeaveCriticalSection(&pFinder->m_cs);  
  
                    // 現在的p剛加入列表,就要delete,肯定會出錯  
                    //delete p;  
                    //p = NULL;  
  
                    //使一個線程從非活動狀態變成活動狀態  
                    ::SetEvent(pFinder->m_hDirEvent);  
                }  
                else //如果是文件  
                {  
                    //判斷是否為要查找的文件   
                    if (pFinder->CheckFile(fileData.cFileName)) //符合查找的文件   
                    {  
                        //打印  
                        ::EnterCriticalSection(&pFinder->m_cs);  
                        pFinder->m_nResultCount++;  
                        ::LeaveCriticalSection(&pFinder->m_cs);  
                        printf("find %d:%s/n", pFinder->m_nResultCount, fileData.cFileName);  
                    }  
                }  
            } while (::FindNextFile(hFindFile, &fileData));  
        }  
        //if (pNode)  
        //{  
        //  delete pNode;  
        //  pNode = NULL;  
        //}  
  
  
    }//end while  
  
    //促使一個搜索線程從WaitForSingleObject返回,并退出循環  
    ::SetEvent(pFinder->m_hDirEvent);  
  
    //判斷此線程是否是最后一個結束循環的線程,如果是就通知主線程  
    if (::WaitForSingleObject(pFinder->m_hDirEvent,0) != WAIT_TIMEOUT)  
    {  
        ::SetEvent(pFinder->m_hExitEvent);  
    }  
    return 1;  
}  
  
void    main()  
{  
    printf("start:/n");  
    CRapidFinder* pFinder = new CRapidFinder(64);  
    CDirectoryNode* pNode = new CDirectoryNode;  
    char szPath[] = "c://";  
    char szFile[] = "config";  
  
    strcpy(pNode->szDir, szPath);  
    pFinder->m_listDir.AddHead(pNode);  
  
    strcpy(pFinder->m_szMatchName, szFile);  
    pFinder->m_nThreadCount = pFinder->m_nMaxThread;  
    //開始開啟多線程  
    for (int i=0;i< pFinder->m_nMaxThread;i++)  
    {  
        ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FinderEntry, pFinder, 0, NULL);  
    }  
  
    //只有m_hExitEvent受信狀態,主線程才恢復運行  
    ::WaitForSingleObject(pFinder->m_hExitEvent,INFINITE);  
    printf("共找到%d/n", pFinder->m_nResultCount);  
    //if (pNode != NULL) delete pNode;  
    if (pFinder != NULL) delete pFinder;  
  
    getchar();  
    return;  
}
rapidfinder.h文件如下:
#include "_AFXTLS_.H"  
  
struct CDirectoryNode: public CNoTrackObject  
{  
    CDirectoryNode* pNext;  
    char szDir[MAX_PATH];  
};  
  
class CRapidFinder  
{  
public:  
    CRapidFinder(int nMaxThread); //構造函數  
    virtual ~CRapidFinder();    //析構函數  
    BOOL    CheckFile(LPCTSTR lpszFileName); //檢查lpszFileName是否符合查找條件  
    int     m_nResultCount; //找到的結果數量  
    int     m_nThreadCount; //當前的線程數量  
    CTypedSimpleList<CDirectoryNode*> m_listDir; //查找目錄  
    CRITICAL_SECTION    m_cs;   //共享  
    const int   m_nMaxThread;   //最大線程數量  
    char    m_szMatchName[MAX_PATH]; //要查找的名稱  
    HANDLE  m_hDirEvent;    //添加新目錄后置位  
    HANDLE  m_hExitEvent;   //所有線程退出時置位  
};
 
下面這兩個類就是實現了simplelist類和模板 
_afxatl.cpp文件:
#include "_AFXTLS_.H"  
  
void CSimpleList::AddHead(void* p)  
{  
    *GetNextPtr(p) = m_pHead;  
    m_pHead = p;  
}  
  
BOOL CSimpleList::Remove(void* p)  
{  
    if (p == NULL)  
    {  
        return FALSE;  
    }  
  
    BOOL bResult = FALSE;  
    if (p == m_pHead)  
    {  
        m_pHead = *GetNextPtr(m_pHead);  
        bResult = TRUE;  
    }  
    else  
    {  
        void* pTest = m_pHead;  
        while (pTest != NULL && *GetNextPtr(pTest) != p)  
        {  
            pTest = *GetNextPtr(pTest);  
        }  
        if (pTest != NULL)  
        {  
            *GetNextPtr(pTest) = *GetNextPtr(p);  
            bResult = TRUE;  
        }  
    }  
  
    return bResult;  
}  
  
void* CNoTrackObject::operator new(size_t nSize)  
{  
    void* p = ::GlobalAlloc(GPTR, nSize);  
    return  p;  
}  
  
void CNoTrackObject::operator delete(void* p)  
{  
    if (p!=NULL)  
    {  
        ::GlobalFree(p);  
    }  
}
 afxatl.h文件:
#ifndef _AFXTLS_H_H  
#define _AFXTLS_H_H  
#include <Windows.h>  
  
class CSimpleList  
{  
public:  
    CSimpleList(int nNextOffset=0);  
    void Construct(int nNextOffset);  
    BOOL IsEmpty() const;  
    void AddHead(void* p);  
    void RemoveAll();  
    void* GetHead() const;  
    void* GetNext(void* p) const;  
    BOOL Remove(void* p);  
  
    //為實現接口所需要的成員  
    void* m_pHead;  
    int m_nNextOffset;  
    void** GetNextPtr(void* p) const;  
};  
  
//類的內聯函數  
inline CSimpleList::CSimpleList(int nNextOffset)  
{m_pHead = NULL; m_nNextOffset = nNextOffset;}  
  
inline void CSimpleList::Construct(int nNextOffset)  
{m_nNextOffset = nNextOffset;}  
  
inline BOOL CSimpleList::IsEmpty() const      
{return m_pHead==NULL;}  
  
inline void CSimpleList::RemoveAll()  
{m_pHead=NULL;}  
  
inline void* CSimpleList::GetHead() const  
{return m_pHead;}  
  
inline void* CSimpleList::GetNext(void* preElement) const  
{  
    return *GetNextPtr(preElement);  
}  
  
inline void** CSimpleList::GetNextPtr(void* p) const  
{  
    return (void**)((BYTE*)p + m_nNextOffset);  
}  
  
class CNoTrackObject  
{  
public:  
    void* operator new(size_t nSize);  
    void operator delete(void*);  
    virtual ~CNoTrackObject(){};  
};  
  
template<class TYPE>  
  
class CTypedSimpleList:public CSimpleList  
{  
public:  
    CTypedSimpleList(int nNextOffset=0)  
        :CSimpleList(nNextOffset){}  
    void AddHead(TYPE p)  
    {  
        CSimpleList::AddHead((void*)p);  
    }  
  
    TYPE GetHead()  
    {  
        return (TYPE)CSimpleList::GetHead();  
    }  
  
    TYPE GetNext(TYPE p)  
    {  
        return (TYPE)CSimpleList::GetNext((void*)p);  
    }  
  
    BOOL Remove(TYPE p)  
    {  
        return CSimpleList::Remove(p);  
    }  
  
    operator TYPE()  
    {  
        return (TYPE)CSimpleList::GetHead();  
    }  
};  
#endif
希望本文所述對大家的C++程序設計有所幫助。