多线程查找文件

来源:互联网 发布:战斧主机 知乎 编辑:程序博客网 时间:2024/06/10 03:39

主要是多线程的互斥 文件 的查找

多线程互斥的框架

[cpp] view plain copy
 print?
  1. //线程函数  
  2. UINT FinderEntry(LPVOID lpParam)  
  3. {  
  4.     //CRapidFinder通过参数传递进来   
  5.     CRapidFinder* pFinder = (CRapidFinder*)lpParam;  
  6.     CDirectoryNode* pNode = NULL;  
  7.     BOOL bActive = TRUE; //bActive为TRUE,表示当前线程激活  
  8.     //循环处理m_listDir列表中的目录  
  9.     while (1)  
  10.     {  
  11.         //从列表中取出一个目录  
  12.         ::EnterCriticalSection(&pFinder->m_cs);  
  13.         if (pFinder->m_listDir.IsEmpty()) //目录列表为空,当前线程不激活,所以bAactive=FALSE  
  14.         {  
  15.             bActive = FALSE;  
  16.         }  
  17.         else  
  18.         {  
  19.             pNode = pFinder->m_listDir.GetHead(); //得到一个目录  
  20.             pFinder->m_listDir.Remove(pNode);    //从目录列表中移除  
  21.         }  
  22.         ::LeaveCriticalSection(&pFinder->m_cs);  
  23.         //如果停止当前线程  
  24.         if (bActive == FALSE)  
  25.         {  
  26.             //停止当前线程  
  27.             //线程数--  
  28.             pFinder->m_nThreadCount--;  
  29.               
  30.             //如果当前活动线程数为0,跳出,结束  
  31.             if (pFinder->m_nThreadCount == 0)  
  32.             {  
  33.                 ::LeaveCriticalSection(&pFinder->m_cs);  
  34.                 break;  
  35.             }  
  36.             ::LeaveCriticalSection(&pFinder->m_cs);  
  37.             //当前活动线程数不为0,等待其他线程向目录列表中加目录  
  38.             ::ResetEvent(pFinder->m_hDirEvent);  
  39.             ::WaitForSingleObject(pFinder->m_hDirEvent, INFINITE);  
  40.   
  41.             //运行到这,就说明其他线程唤醒了本线程  
  42.               
  43.             pFinder->m_nThreadCount++; //激活了自己的线程,线程数++  
  44.               
  45.             bActive = TRUE; //当前线程活了  
  46.             continue//跳到while,  
  47.         }  
  48.         //从目录列表中成功取得了目录  
  49. <span style="white-space:pre">      </span>......................  
  50.           
  51.         //if (pNode)  
  52.         //{  
  53.         //  delete pNode;  
  54.         //  pNode = NULL;  
  55.         //}  
  56.   
  57.   
  58.     }//end while  
  59.   
  60.     //促使一个搜索线程从WaitForSingleObject返回,并退出循环  
  61.     ::SetEvent(pFinder->m_hDirEvent);  
  62.   
  63.     //判断此线程是否是最后一个结束循环的线程,如果是就通知主线程  
  64.     if (::WaitForSingleObject(pFinder->m_hDirEvent,0) != WAIT_TIMEOUT)  
  65.     {  
  66.         ::SetEvent(pFinder->m_hExitEvent);  
  67.     }  
  68.     return 1;  
  69. }  



查找文件 的框架:

[python] view plain copy
 print?
  1. //从目录列表中成功取得了目录  
  2.         WIN32_FIND_DATA fileData;  
  3.         HANDLE hFindFile;  
  4.         //生成正确的查找字符串  
  5.         if (pNode->szDir[strlen(pNode->szDir)-1] != '\\')  
  6.         {  
  7.             strcat(pNode->szDir,"\\");  
  8.         }  
  9.         strcat(pNode->szDir, "*.*");  
  10.         //查找文件的框架  
  11.         hFindFile = ::FindFirstFile(pNode->szDir, &fileData);  
  12.         if (hFindFile != INVALID_HANDLE_VALUE )  
  13.         {  
  14.             do   
  15.             {  
  16.                 //如果是当前目录,跳过  
  17.                 if (fileData.cFileName[0] == '.')  
  18.                 {  
  19.                     continue;  
  20.                 }  
  21.                 //如果是目录  
  22.                 if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)  
  23.                 {  
  24.                     //将当前目录加入到目录列表  
  25.                     。。。。。。  
  26.                     //使一个线程从非活动状态变成活动状态  
  27.                     ::SetEvent(pFinder->m_hDirEvent);  
  28.                 }  
  29.                 else //如果是文件  
  30.                 {  
  31.                     。。。。。。。。。。。。。  
  32.                 }  
  33.             } while (::FindNextFile(hFindFile, &fileData));  
  34.         }  

所有代码main.cpp:

[cpp] view plain copy
 print?
  1. #include "RapidFinder.h"  
  2. #include <stddef.h>  
  3. #include <stdio.h>  
  4. #include <process.h>  
  5.   
  6. //m_nMaxThread 是const int类型,只能通过这种方式初始化  
  7. CRapidFinder::CRapidFinder(int nMaxThread):m_nMaxThread(nMaxThread)  
  8. {  
  9.     m_nResultCount = 0;  
  10.     m_nThreadCount = 0;  
  11.     m_listDir.Construct(offsetof(CDirectoryNode, pNext));  //offsetof在stddef.h头文件中  
  12.     ::InitializeCriticalSection(&m_cs);  
  13.     m_szMatchName[0] = '\0';  
  14.     m_hDirEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);  
  15.     m_hExitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);  
  16.   
  17. }  
  18.   
  19. CRapidFinder::~CRapidFinder()  
  20. {  
  21.     ::DeleteCriticalSection(&m_cs);  
  22.     ::CloseHandle(m_hDirEvent);  
  23.     ::CloseHandle(m_hExitEvent);  
  24. }  
  25.   
  26. BOOL    CRapidFinder::CheckFile(LPCTSTR lpszFileName)  
  27. {  
  28.     //定义两个字符串  
  29.     char string[MAX_PATH];  
  30.     char strSearch[MAX_PATH];  
  31.     strcpy(string, lpszFileName);  
  32.     strcpy(strSearch, m_szMatchName);  
  33.   
  34.     //将字符串大写  
  35.     _strupr(string);  
  36.     _strupr(strSearch);  
  37.   
  38.     //比较string中是否含有strSearch  
  39.     if (strstr(string, strSearch) != NULL)  
  40.     {  
  41.         return TRUE;  
  42.     }  
  43.     return FALSE;  
  44. }  
  45.   
  46.   
  47. //线程函数  
  48. UINT FinderEntry(LPVOID lpParam)  
  49. {  
  50.     //CRapidFinder通过参数传递进来   
  51.     CRapidFinder* pFinder = (CRapidFinder*)lpParam;  
  52.     CDirectoryNode* pNode = NULL;  
  53.     BOOL bActive = TRUE; //bActive为TRUE,表示当前线程激活  
  54.     //循环处理m_listDir列表中的目录  
  55.     while (1)  
  56.     {  
  57.         //从列表中取出一个目录  
  58.         ::EnterCriticalSection(&pFinder->m_cs);  
  59.         if (pFinder->m_listDir.IsEmpty()) //目录列表为空,当前线程不激活,所以bAactive=FALSE  
  60.         {  
  61.             bActive = FALSE;  
  62.         }  
  63.         else  
  64.         {  
  65.             pNode = pFinder->m_listDir.GetHead(); //得到一个目录  
  66.             pFinder->m_listDir.Remove(pNode);    //从目录列表中移除  
  67.         }  
  68.         ::LeaveCriticalSection(&pFinder->m_cs);  
  69.         //如果停止当前线程  
  70.         if (bActive == FALSE)  
  71.         {  
  72.             //停止当前线程  
  73.             ::EnterCriticalSection(&pFinder->m_cs);  
  74.             pFinder->m_nThreadCount--;  
  75.               
  76.             //如果当前活动线程数为0,跳出,结束  
  77.             if (pFinder->m_nThreadCount == 0)  
  78.             {  
  79.                 ::LeaveCriticalSection(&pFinder->m_cs);  
  80.                 break;  
  81.             }  
  82.             ::LeaveCriticalSection(&pFinder->m_cs);  
  83.             //当前活动线程数不为0,等待其他线程向目录列表中加目录  
  84.             ::ResetEvent(pFinder->m_hDirEvent);  
  85.             ::WaitForSingleObject(pFinder->m_hDirEvent, INFINITE);  
  86.   
  87.             //运行到这,就说明其他线程向目录列表中加入了新的目录  
  88.             ::EnterCriticalSection(&pFinder->m_cs);  
  89.             pFinder->m_nThreadCount++; //激活了自己的线程,线程数++  
  90.             ::LeaveCriticalSection(&pFinder->m_cs);  
  91.             bActive = TRUE; //目录不再为空  
  92.             continue//跳到while,重新在目录列表中取目录  
  93.         }  
  94.         //从目录列表中成功取得了目录  
  95.         WIN32_FIND_DATA fileData;  
  96.         HANDLE hFindFile;  
  97.         //生成正确的查找字符串  
  98.         if (pNode->szDir[strlen(pNode->szDir)-1] != '\\')  
  99.         {  
  100.             strcat(pNode->szDir,"\\");  
  101.         }  
  102.         strcat(pNode->szDir, "*.*");  
  103.         //查找文件的框架  
  104.         hFindFile = ::FindFirstFile(pNode->szDir, &fileData);  
  105.         if (hFindFile != INVALID_HANDLE_VALUE )  
  106.         {  
  107.             do   
  108.             {  
  109.                 //如果是当前目录,跳过  
  110.                 if (fileData.cFileName[0] == '.')  
  111.                 {  
  112.                     continue;  
  113.                 }  
  114.                 //如果是目录  
  115.                 if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)  
  116.                 {  
  117.                     //将当前目录加入到目录列表  
  118.                     CDirectoryNode* p = new CDirectoryNode;  
  119.                     strncpy(p->szDir, pNode->szDir, strlen(pNode->szDir)-3); //将pNode后面的*.*三位去掉  
  120.                     strcat(p->szDir, fileData.cFileName);  
  121.                     ::EnterCriticalSection(&pFinder->m_cs);  
  122.                     pFinder->m_listDir.AddHead(p);  
  123.                     ::LeaveCriticalSection(&pFinder->m_cs);  
  124.   
  125.                     // 现在的p刚加入列表,就要delete,肯定会出错  
  126.                     //delete p;  
  127.                     //p = NULL;  
  128.   
  129.                     //使一个线程从非活动状态变成活动状态  
  130.                     ::SetEvent(pFinder->m_hDirEvent);  
  131.                 }  
  132.                 else //如果是文件  
  133.                 {  
  134.                     //判断是否为要查找的文件   
  135.                     if (pFinder->CheckFile(fileData.cFileName)) //符合查找的文件   
  136.                     {  
  137.                         //打印  
  138.                         ::EnterCriticalSection(&pFinder->m_cs);  
  139.                         pFinder->m_nResultCount++;  
  140.                         ::LeaveCriticalSection(&pFinder->m_cs);  
  141.                         printf("find %d:%s\n", pFinder->m_nResultCount, fileData.cFileName);  
  142.                     }  
  143.                 }  
  144.             } while (::FindNextFile(hFindFile, &fileData));  
  145.         }  
  146.         //if (pNode)  
  147.         //{  
  148.         //  delete pNode;  
  149.         //  pNode = NULL;  
  150.         //}  
  151.   
  152.   
  153.     }//end while  
  154.   
  155.     //促使一个搜索线程从WaitForSingleObject返回,并退出循环  
  156.     ::SetEvent(pFinder->m_hDirEvent);  
  157.   
  158.     //判断此线程是否是最后一个结束循环的线程,如果是就通知主线程  
  159.     if (::WaitForSingleObject(pFinder->m_hDirEvent,0) != WAIT_TIMEOUT)  
  160.     {  
  161.         ::SetEvent(pFinder->m_hExitEvent);  
  162.     }  
  163.     return 1;  
  164. }  
  165.   
  166.   
  167. void    main()  
  168. {  
  169.     printf("start:\n");  
  170.     CRapidFinder* pFinder = new CRapidFinder(64);  
  171.     CDirectoryNode* pNode = new CDirectoryNode;  
  172.     char szPath[] = "c:\\";  
  173.     char szFile[] = "config";  
  174.   
  175.     strcpy(pNode->szDir, szPath);  
  176.     pFinder->m_listDir.AddHead(pNode);  
  177.   
  178.     strcpy(pFinder->m_szMatchName, szFile);  
  179.     pFinder->m_nThreadCount = pFinder->m_nMaxThread;  
  180.     //开始开启多线程  
  181.     for (int i=0;i< pFinder->m_nMaxThread;i++)  
  182.     {  
  183.         ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)FinderEntry, pFinder, 0, NULL);  
  184.     }  
  185.   
  186.     //只有m_hExitEvent受信状态,主线程才恢复运行  
  187.     ::WaitForSingleObject(pFinder->m_hExitEvent,INFINITE);  
  188.     printf("共找到%d\n", pFinder->m_nResultCount);  
  189.     //if (pNode != NULL) delete pNode;  
  190.     if (pFinder != NULL) delete pFinder;  
  191.   
  192.     getchar();  
  193.     return;  
  194. }  


rapidfinder.h

[python] view plain copy
 print?
  1. #include "_AFXTLS_.H"  
  2.   
  3. struct CDirectoryNode: public CNoTrackObject  
  4. {  
  5.     CDirectoryNode* pNext;  
  6.     char szDir[MAX_PATH];  
  7. };  
  8.   
  9. class CRapidFinder  
  10. {  
  11. public:  
  12.     CRapidFinder(int nMaxThread); //构造函数  
  13.     virtual ~CRapidFinder();    //析构函数  
  14.     BOOL    CheckFile(LPCTSTR lpszFileName); //检查lpszFileName是否符合查找条件  
  15.     int     m_nResultCount; //找到的结果数量  
  16.     int     m_nThreadCount; //当前的线程数量  
  17.     CTypedSimpleList<CDirectoryNode*> m_listDir; //查找目录  
  18.     CRITICAL_SECTION    m_cs;   //共享  
  19.     const int   m_nMaxThread;   //最大线程数量  
  20.     char    m_szMatchName[MAX_PATH]; //要查找的名称  
  21.     HANDLE  m_hDirEvent;    //添加新目录后置位  
  22.     HANDLE  m_hExitEvent;   //所有线程退出时置位  
  23. };  



--------------------------------------------------------------------------------------------------

 下面这两个类就是实现了simplelist类和模板 

_afxatl.cpp  

[python] view plain copy
 print?
  1. #include "_AFXTLS_.H"  
  2.   
  3. void CSimpleList::AddHead(void* p)  
  4. {  
  5.     *GetNextPtr(p) = m_pHead;  
  6.     m_pHead = p;  
  7. }  
  8.   
  9. BOOL CSimpleList::Remove(void* p)  
  10. {  
  11.     if (p == NULL)  
  12.     {  
  13.         return FALSE;  
  14.     }  
  15.   
  16.     BOOL bResult = FALSE;  
  17.     if (p == m_pHead)  
  18.     {  
  19.         m_pHead = *GetNextPtr(m_pHead);  
  20.         bResult = TRUE;  
  21.     }  
  22.     else  
  23.     {  
  24.         void* pTest = m_pHead;  
  25.         while (pTest != NULL && *GetNextPtr(pTest) != p)  
  26.         {  
  27.             pTest = *GetNextPtr(pTest);  
  28.         }  
  29.         if (pTest != NULL)  
  30.         {  
  31.             *GetNextPtr(pTest) = *GetNextPtr(p);  
  32.             bResult = TRUE;  
  33.         }  
  34.     }  
  35.   
  36.     return bResult;  
  37. }  
  38.   
  39.   
  40. void* CNoTrackObject::operator new(size_t nSize)  
  41. {  
  42.     void* p = ::GlobalAlloc(GPTR, nSize);  
  43.     return  p;  
  44. }  
  45.   
  46. void CNoTrackObject::operator delete(void* p)  
  47. {  
  48.     if (p!=NULL)  
  49.     {  
  50.         ::GlobalFree(p);  
  51.     }  
  52. }  

afxatl.h

[python] view plain copy
 print?
  1. #ifndef _AFXTLS_H_H  
  2. #define _AFXTLS_H_H  
  3. #include <Windows.h>  
  4.   
  5. class CSimpleList  
  6. {  
  7. public:  
  8.     CSimpleList(int nNextOffset=0);  
  9.     void Construct(int nNextOffset);  
  10.     BOOL IsEmpty() const;  
  11.     void AddHead(void* p);  
  12.     void RemoveAll();  
  13.     void* GetHead() const;  
  14.     void* GetNext(void* p) const;  
  15.     BOOL Remove(void* p);  
  16.   
  17.     //为实现接口所需要的成员  
  18.     void* m_pHead;  
  19.     int m_nNextOffset;  
  20.     void** GetNextPtr(void* p) const;  
  21. };  
  22.   
  23. //类的内联函数  
  24. inline CSimpleList::CSimpleList(int nNextOffset)  
  25. {m_pHead = NULL; m_nNextOffset = nNextOffset;}  
  26.   
  27. inline void CSimpleList::Construct(int nNextOffset)  
  28. {m_nNextOffset = nNextOffset;}  
  29.   
  30. inline BOOL CSimpleList::IsEmpty() const      
  31. {return m_pHead==NULL;}  
  32.   
  33. inline void CSimpleList::RemoveAll()  
  34. {m_pHead=NULL;}  
  35.   
  36. inline void* CSimpleList::GetHead() const  
  37. {return m_pHead;}  
  38.   
  39. inline void* CSimpleList::GetNext(void* preElement) const  
  40. {  
  41.     return *GetNextPtr(preElement);  
  42. }  
  43.   
  44. inline void** CSimpleList::GetNextPtr(void* p) const  
  45. {  
  46.     return (void**)((BYTE*)p + m_nNextOffset);  
  47. }  
  48.   
  49.   
  50. class CNoTrackObject  
  51. {  
  52. public:  
  53.     void* operator new(size_t nSize);  
  54.     void operator delete(void*);  
  55.     virtual ~CNoTrackObject(){};  
  56. };  
  57.   
  58. template<class TYPE>  
  59.   
  60. class CTypedSimpleList:public CSimpleList  
  61. {  
  62. public:  
  63.     CTypedSimpleList(int nNextOffset=0)  
  64.         :CSimpleList(nNextOffset){}  
  65.     void AddHead(TYPE p)  
  66.     {  
  67.         CSimpleList::AddHead((void*)p);  
  68.     }  
  69.   
  70.     TYPE GetHead()  
  71.     {  
  72.         return (TYPE)CSimpleList::GetHead();  
  73.     }  
  74.   
  75.     TYPE GetNext(TYPE p)  
  76.     {  
  77.         return (TYPE)CSimpleList::GetNext((void*)p);  
  78.     }  
  79.   
  80.     BOOL Remove(TYPE p)  
  81.     {  
  82.         return CSimpleList::Remove(p);  
  83.     }  
  84.   
  85.     operator TYPE()  
  86.     {  
  87.         return (TYPE)CSimpleList::GetHead();  
  88.     }  
  89. };  
  90. #endif  
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 淘宝店铺异常2怎么办 付款付错了怎么办 手机淘宝太卡怎么办 卖家不同意退货怎么办 游戏退出无响应怎么办 手机淘宝购物车打不开怎么办 淘宝店铺没有访客怎么办 淘宝店铺0流量怎么办 微信经常封号怎么办 网上拍卖堂违约怎么办 dnf4开组队制裁怎么办 红酒木塞丢了怎么办 红酒塞子进去了怎么办 淘金币即将过期怎么办 淘金币过期怎么办2018 换详情排名下降怎么办 长城宽带不用了怎么办 快递到了想退货怎么办 淘宝退货商家拒收怎么办 淘宝运费险失败怎么办 忘记购买运费险怎么办 咸鱼买家申请退款怎么办 熟猪肉有点变味怎么办 和领导意见不一致怎么办 骑手提前点送达怎么办 ubuntu安装报错怎么办 液相色谱两峰分不开怎么办 液相色谱柱老堵怎么办? 没有装usb驱动怎么办 ipad速度越来越慢怎么办 美萍管理软件打不开怎么办 小米4开机黑屏怎么办 小米电脑死机了怎么办 小米8手机死机怎么办 oppa7开不了机怎么办 oppo手机wlan打不开怎么办 三星s6进水黑屏怎么办 银行卡不支持快捷支付怎么办 路由器忘记管理员密码怎么办 云付没有推荐人怎么办 牛呗审核不通过怎么办