欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++實(shí)現(xiàn)多線程查找文件實(shí)例

 更新時(shí)間:2014年10月12日 17:13:25   投稿:shichen2014  
這篇文章主要介紹了C++實(shí)現(xiàn)多線程查找文件實(shí)例,對(duì)于深入學(xué)習(xí)C++程序設(shè)計(jì)有著很好的參考借鑒價(jià)值,需要的朋友可以參考下

主要是多線程的互斥 文件 的查找
多線程互斥的框架

復(fù)制代碼 代碼如下:
//線程函數(shù) 
UINT FinderEntry(LPVOID lpParam) 

    //CRapidFinder通過參數(shù)傳遞進(jìn)來  
    CRapidFinder* pFinder = (CRapidFinder*)lpParam; 
    CDirectoryNode* pNode = NULL; 
    BOOL bActive = TRUE; //bActive為TRUE,表示當(dāng)前線程激活 
    //循環(huán)處理m_listDir列表中的目錄 
    while (1) 
    { 
        //從列表中取出一個(gè)目錄 
        ::EnterCriticalSection(&pFinder->m_cs); 
        if (pFinder->m_listDir.IsEmpty()) //目錄列表為空,當(dāng)前線程不激活,所以bAactive=FALSE 
        { 
            bActive = FALSE; 
        } 
        else 
        { 
            pNode = pFinder->m_listDir.GetHead(); //得到一個(gè)目錄 
            pFinder->m_listDir.Remove(pNode);    //從目錄列表中移除 
        } 
        ::LeaveCriticalSection(&pFinder->m_cs); 
        //如果停止當(dāng)前線程 
        if (bActive == FALSE) 
        { 
            //停止當(dāng)前線程 
            //線程數(shù)-- 
            pFinder->m_nThreadCount--; 
             
            //如果當(dāng)前活動(dòng)線程數(shù)為0,跳出,結(jié)束 
            if (pFinder->m_nThreadCount == 0) 
            { 
                ::LeaveCriticalSection(&pFinder->m_cs); 
                break; 
            } 
            ::LeaveCriticalSection(&pFinder->m_cs); 
            //當(dāng)前活動(dòng)線程數(shù)不為0,等待其他線程向目錄列表中加目錄 
            ::ResetEvent(pFinder->m_hDirEvent); 
            ::WaitForSingleObject(pFinder->m_hDirEvent, INFINITE); 
 
            //運(yùn)行到這,就說明其他線程喚醒了本線程 
             
            pFinder->m_nThreadCount++; //激活了自己的線程,線程數(shù)++ 
             
            bActive = TRUE; //當(dāng)前線程活了 
            continue; //跳到while, 
        } 
        //從目錄列表中成功取得了目錄 
<span style="white-space:pre">      </span>...................... 
         
        //if (pNode) 
        //{ 
        //  delete pNode; 
        //  pNode = NULL; 
        //} 
 
 
    }//end while 
 
    //促使一個(gè)搜索線程從WaitForSingleObject返回,并退出循環(huán) 
    ::SetEvent(pFinder->m_hDirEvent); 
 
    //判斷此線程是否是最后一個(gè)結(jié)束循環(huán)的線程,如果是就通知主線程 
    if (::WaitForSingleObject(pFinder->m_hDirEvent,0) != WAIT_TIMEOUT) 
    { 
        ::SetEvent(pFinder->m_hExitEvent); 
    } 
    return 1; 
}
 

查找文件 的框架:

復(fù)制代碼 代碼如下:
//從目錄列表中成功取得了目錄 
WIN32_FIND_DATA fileData; 
HANDLE hFindFile; 
//生成正確的查找字符串 
if (pNode->szDir[strlen(pNode->szDir)-1] != '\\') 

    strcat(pNode->szDir,"\\"); 

strcat(pNode->szDir, "*.*"); 
//查找文件的框架 
hFindFile = ::FindFirstFile(pNode->szDir, &fileData); 
if (hFindFile != INVALID_HANDLE_VALUE ) 

    do  
    { 
 //如果是當(dāng)前目錄,跳過 
 if (fileData.cFileName[0] == '.') 
 { 
     continue; 
 } 
 //如果是目錄 
 if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 
 { 
     //將當(dāng)前目錄加入到目錄列表 
     。。。。。。 
     //使一個(gè)線程從非活動(dòng)狀態(tài)變成活動(dòng)狀態(tài) 
     ::SetEvent(pFinder->m_hDirEvent); 
 } 
 else //如果是文件 
 { 
     。。。。。。。。。。。。。 
 } 
    } while (::FindNextFile(hFindFile, &fileData)); 
}
 

所有代碼main.cpp:

復(fù)制代碼 代碼如下:
#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) 

    //定義兩個(gè)字符串 
    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; 
}
 
//線程函數(shù) 
UINT FinderEntry(LPVOID lpParam) 

    //CRapidFinder通過參數(shù)傳遞進(jìn)來  
    CRapidFinder* pFinder = (CRapidFinder*)lpParam; 
    CDirectoryNode* pNode = NULL; 
    BOOL bActive = TRUE; //bActive為TRUE,表示當(dāng)前線程激活 
    //循環(huán)處理m_listDir列表中的目錄 
    while (1) 
    { 
        //從列表中取出一個(gè)目錄 
        ::EnterCriticalSection(&pFinder->m_cs); 
        if (pFinder->m_listDir.IsEmpty()) //目錄列表為空,當(dāng)前線程不激活,所以bAactive=FALSE 
        { 
            bActive = FALSE; 
        } 
        else 
        { 
            pNode = pFinder->m_listDir.GetHead(); //得到一個(gè)目錄 
            pFinder->m_listDir.Remove(pNode);    //從目錄列表中移除 
        } 
        ::LeaveCriticalSection(&pFinder->m_cs); 
        //如果停止當(dāng)前線程 
        if (bActive == FALSE) 
        { 
            //停止當(dāng)前線程 
            ::EnterCriticalSection(&pFinder->m_cs); 
            pFinder->m_nThreadCount--; 
             
            //如果當(dāng)前活動(dòng)線程數(shù)為0,跳出,結(jié)束 
            if (pFinder->m_nThreadCount == 0) 
            { 
                ::LeaveCriticalSection(&pFinder->m_cs); 
                break; 
            } 
            ::LeaveCriticalSection(&pFinder->m_cs); 
            //當(dāng)前活動(dòng)線程數(shù)不為0,等待其他線程向目錄列表中加目錄 
            ::ResetEvent(pFinder->m_hDirEvent); 
            ::WaitForSingleObject(pFinder->m_hDirEvent, INFINITE); 
 
            //運(yùn)行到這,就說明其他線程向目錄列表中加入了新的目錄 
            ::EnterCriticalSection(&pFinder->m_cs); 
            pFinder->m_nThreadCount++; //激活了自己的線程,線程數(shù)++ 
            ::LeaveCriticalSection(&pFinder->m_cs); 
            bActive = TRUE; //目錄不再為空 
            continue; //跳到while,重新在目錄列表中取目錄 
        } 
        //從目錄列表中成功取得了目錄 
        WIN32_FIND_DATA fileData; 
        HANDLE hFindFile; 
        //生成正確的查找字符串 
        if (pNode->szDir[strlen(pNode->szDir)-1] != '\\') 
        { 
            strcat(pNode->szDir,"\\"); 
        } 
        strcat(pNode->szDir, "*.*"); 
        //查找文件的框架 
        hFindFile = ::FindFirstFile(pNode->szDir, &fileData); 
        if (hFindFile != INVALID_HANDLE_VALUE ) 
        { 
            do  
            { 
                //如果是當(dāng)前目錄,跳過 
                if (fileData.cFileName[0] == '.') 
                { 
                    continue; 
                } 
                //如果是目錄 
                if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 
                { 
                    //將當(dāng)前目錄加入到目錄列表 
                    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); 
 
                    // 現(xiàn)在的p剛加入列表,就要delete,肯定會(huì)出錯(cuò) 
                    //delete p; 
                    //p = NULL; 
 
                    //使一個(gè)線程從非活動(dòng)狀態(tài)變成活動(dòng)狀態(tài) 
                    ::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 
 
    //促使一個(gè)搜索線程從WaitForSingleObject返回,并退出循環(huán) 
    ::SetEvent(pFinder->m_hDirEvent); 
 
    //判斷此線程是否是最后一個(gè)結(jié)束循環(huán)的線程,如果是就通知主線程 
    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受信狀態(tài),主線程才恢復(fù)運(yùn)行 
    ::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文件如下:

復(fù)制代碼 代碼如下:
#include "_AFXTLS_.H" 
 
struct CDirectoryNode: public CNoTrackObject 

    CDirectoryNode* pNext; 
    char szDir[MAX_PATH]; 
}; 
 
class CRapidFinder 

public: 
    CRapidFinder(int nMaxThread); //構(gòu)造函數(shù) 
    virtual ~CRapidFinder();    //析構(gòu)函數(shù) 
    BOOL    CheckFile(LPCTSTR lpszFileName); //檢查lpszFileName是否符合查找條件 
    int     m_nResultCount; //找到的結(jié)果數(shù)量 
    int     m_nThreadCount; //當(dāng)前的線程數(shù)量 
    CTypedSimpleList<CDirectoryNode*> m_listDir; //查找目錄 
    CRITICAL_SECTION    m_cs;   //共享 
    const int   m_nMaxThread;   //最大線程數(shù)量 
    char    m_szMatchName[MAX_PATH]; //要查找的名稱 
    HANDLE  m_hDirEvent;    //添加新目錄后置位 
    HANDLE  m_hExitEvent;   //所有線程退出時(shí)置位 
};
 


下面這兩個(gè)類就是實(shí)現(xiàn)了simplelist類和模板
_afxatl.cpp文件:

復(fù)制代碼 代碼如下:
#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文件:

復(fù)制代碼 代碼如下:
#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); 
 
    //為實(shí)現(xiàn)接口所需要的成員 
    void* m_pHead; 
    int m_nNextOffset; 
    void** GetNextPtr(void* p) const; 
}; 
 
//類的內(nèi)聯(lián)函數(shù) 
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

希望本文所述對(duì)大家的C++程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • c++如何實(shí)現(xiàn)歸并兩個(gè)有序鏈表

    c++如何實(shí)現(xiàn)歸并兩個(gè)有序鏈表

    這篇文章主要介紹了c++如何實(shí)現(xiàn)歸并兩個(gè)有序鏈表,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • 用C++實(shí)現(xiàn)一個(gè)命令行進(jìn)度條的示例代碼

    用C++實(shí)現(xiàn)一個(gè)命令行進(jìn)度條的示例代碼

    這篇文章主要介紹了用C++實(shí)現(xiàn)一個(gè)命令行進(jìn)度條的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • 用C語(yǔ)言簡(jiǎn)單實(shí)現(xiàn)掃雷小游戲

    用C語(yǔ)言簡(jiǎn)單實(shí)現(xiàn)掃雷小游戲

    這篇文章主要為大家詳細(xì)介紹了用C語(yǔ)言簡(jiǎn)單實(shí)現(xiàn)掃雷小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • c++中冒號(hào)(:)和雙冒號(hào)(::)的使用說明

    c++中冒號(hào)(:)和雙冒號(hào)(::)的使用說明

    以下是對(duì)c++中冒號(hào)和雙冒號(hào)的用法進(jìn)行了介紹,需要的朋友可以過來參考下
    2013-07-07
  • 七大經(jīng)典排序算法圖解

    七大經(jīng)典排序算法圖解

    本文詳細(xì)講解了七大經(jīng)典排序算法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • C++中獲取UTC時(shí)間精確到微秒的實(shí)現(xiàn)代碼

    C++中獲取UTC時(shí)間精確到微秒的實(shí)現(xiàn)代碼

    本篇文章是對(duì)C++中獲取UTC時(shí)間精確到微秒的實(shí)現(xiàn)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 利用C++實(shí)現(xiàn)計(jì)算機(jī)輔助教學(xué)系統(tǒng)

    利用C++實(shí)現(xiàn)計(jì)算機(jī)輔助教學(xué)系統(tǒng)

    我們都知道計(jì)算機(jī)在教育中起的作用越來越大。這篇文章主要為大家詳細(xì)介紹了如何利用C++編寫一個(gè)計(jì)算機(jī)輔助教學(xué)系統(tǒng),感興趣的可以了解一下
    2023-05-05
  • C++實(shí)現(xiàn)紅黑樹核心插入實(shí)例代碼

    C++實(shí)現(xiàn)紅黑樹核心插入實(shí)例代碼

    紅黑樹是一種二叉搜索樹,但在每個(gè)結(jié)點(diǎn)上增加一個(gè)存儲(chǔ)位表示結(jié)點(diǎn)的顏色,可以是Red或Black,下面這篇文章主要給大家介紹了關(guān)于C++實(shí)現(xiàn)紅黑樹核心插入的相關(guān)資料,需要的朋友可以參考下
    2023-06-06
  • c語(yǔ)言中的文件加密與解密

    c語(yǔ)言中的文件加密與解密

    這篇文章主要介紹了c語(yǔ)言中的文件加密與解密方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • C++?ASIO實(shí)現(xiàn)異步套接字管理詳解

    C++?ASIO實(shí)現(xiàn)異步套接字管理詳解

    Boost?ASIO(Asynchronous?I/O)是一個(gè)用于異步I/O操作的C++庫(kù),該框架提供了一種方便的方式來處理網(wǎng)絡(luò)通信、多線程編程和異步操作,本文介紹了如何通過ASIO框架實(shí)現(xiàn)一個(gè)簡(jiǎn)單的異步網(wǎng)絡(luò)套接字應(yīng)用程序,需要的可以參考下
    2023-08-08

最新評(píng)論