多线程查找文件
来源:互联网 发布:战斧主机 知乎 编辑:程序博客网 时间:2024/06/10 03:39
主要是多线程的互斥 文件 的查找
多线程互斥的框架
[cpp] view plain copy print?
- //线程函数
- 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;
- }
[python] view plain copy print?
- //从目录列表中成功取得了目录
- 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
- {
- //如果是当前目录,跳过
- if (fileData.cFileName[0] == '.')
- {
- continue;
- }
- //如果是目录
- if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- {
- //将当前目录加入到目录列表
- 。。。。。。
- //使一个线程从非活动状态变成活动状态
- ::SetEvent(pFinder->m_hDirEvent);
- }
- else //如果是文件
- {
- 。。。。。。。。。。。。。
- }
- } while (::FindNextFile(hFindFile, &fileData));
- }
所有代码main.cpp:
[cpp] view plain copy print?
- #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,"\\");
- }
- 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
[python] view plain copy print?
- #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[python] view plain copy print?
- #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
[python] view plain copy print?
- #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
阅读全文
0 0
- 多线程查找文件
- 多线程查找文件
- 多线程查找
- 查找文件
- 查找文件
- 文件查找
- 文件查找
- 查找文件
- 查找文件
- 查找文件
- 查找文件
- 查找文件
- 文件查找
- 文件查找
- 文件查找
- 文件查找
- 文件查找
- 查找文件
- hdu 6109 数据分割(并查集+set合并)
- HDU 6130-Kolakoski(Kolakoski序列)
- 仿qq空间标题变色和仿知乎列表滑动隐藏和显示效果
- MOOC清华《面向对象程序设计》第2章:函数重载实验
- 普元 EOS Platform 7.6 coframe给用户授权了系统管理员的角色,登录后点击“启动流程”菜单,看不到可以启动的流程定义
- 多线程查找文件
- 路径统计(最短路计数)
- 2017年8月14日(模拟6 smoj2060,2061,2062暴力模拟、数学方法求gcd(a^b,c^d)、动态规划)
- 0 数据结构和算法绪论
- (12) 逻辑结构-每天五分钟学习数据结构
- 无法观看coursera视频解决办法
- tensorflow slim layers
- 黑人是晒黑的吗
- 大学毕业一年回忆录