WEB开发网
开发学院软件开发VC 一个用多线程实现文件查找的例子 阅读

一个用多线程实现文件查找的例子

 2006-07-20 11:42:06 来源:WEB开发网   
核心提示: 编程思路:定义一个临时目录列表CStringList m_DirList; 线程每找到一个目录就将它放在m_DirList尾,若找到的是文件,一个用多线程实现文件查找的例子(2),就用MatchProc()进行比较,判断是否符合查找条件,还请大家指正,欢迎与我联系:jruv@163.com

编程思路:

定义一个临时目录列表CStringList m_DirList; 线程每找到一个目录就将它放在m_DirList尾,若找到的是文件,就用MatchProc()进行比较,判断是否符合查找条件。若符合就向UI线程发送消息WM_FINDERITEM,以进行界面显示。然后,线程继续在当前目录中查找直到当前目录全部查找完毕。再从m_DirList队头取一个新的目录进行查找。

这里有一个要注意的地方就是m_DirList为每个线程所共有的资源,所以在访问m_DirList时要注意一下线程间的互斥,这可以用临界区操作来保证。

那么,如何来判断文件查找应该结束了呢?仅判断m_DirList为空是不够的,因为当m_DirList为空时,有可能还有活动的线程,这些活动的线程可能还会产生新的未查找的目录,故只有在m_DirList为空且当前的活动线程数为0时才可以断定查找结束。(这里的"活动线程"指正在进行查找操作的线程,"非活动线程"指处于等待新的待查目录状态的线程)

这部分在线程函数中实现:

DWORD WINAPI CRapidFinder::ThreadProc(LPVOID lpParam)
{
  CRapidFinder *finder=(CRapidFinder *)lpParam;
  CFileFind filefinder;
  CStringList filelist;
  CString PathStr;
  CString CurPath;
  int re;
  BYTE bNewActive=1,bOldActive;
  CString *lpFolder=new CString;
  while(1)
  {
    bOldActive=bNewActive;
    if(WaitForSingleObject(finder->m_hExitEvent,0)!=WAIT_TIMEOUT)
    {
      if(bOldActive)InterlockedDecrement(&finder->m_ActiveCount);
      PostMessage(finder->m_MainhWnd,WM_THREADCOUNT,(WPARAM)finder->m_ActiveCount,NULL);
      break;
    }
   
    if(!finder->m_ActiveCount)
    {
      SetEvent(finder->m_hExitEvent);
      finder->m_ExitCode=finder->EXIT;
      break;
    }
     //进入临界区
    EnterCriticalSection(&finder->m_gCriticalSection);
    if(finder->m_DirList.IsEmpty())bNewActive=0;
    else
    {
       bNewActive=1;
      *lpFolder=finder->m_DirList.RemoveHead();
       CurPath=*lpFolder+_T("\\*.*");
    }
    LeaveCriticalSection(&finder->m_gCriticalSection);
    //离开临界区
   
   if(bNewActive!=bOldActive)
   {
     bNewActive?InterlockedIncrement(&finder->m_ActiveCount):InterlockedDecrement(&finder->m_ActiveCount);
     PostMessage(finder->m_MainhWnd,WM_THREADCOUNT,(WPARAM)finder->m_ActiveCount,NULL);
   }
   else if(!bNewActive) continue;
   
   SendMessage(finder->m_MainhWnd,WM_FINDERFOLDER,(WPARAM)lpFolder,NULL);
    if(filefinder.FindFile(LPCTSTR(CurPath)))
    {
      do
      {
        re=filefinder.FindNextFile();
        if(filefinder.IsDots())continue;
        PathStr=filefinder.GetFilePath();
        if(filefinder.IsDirectory())
        {
          EnterCriticalSection(&finder->m_gCriticalSection);
          finder->m_DirList.AddTail(PathStr);
          LeaveCriticalSection(&finder->m_gCriticalSection);
        }
        else filelist.AddTail(PathStr);
      }while(re);
    }
    while(!filelist.IsEmpty())
    {
      PathStr=filelist.RemoveHead();
      if(finder->MatchProc(PathStr))
        SendMessage(finder->m_MainhWnd,WM_FINDERITEM,(WPARAM)&PathStr,NULL);
    }
  }
delete lpFolder;
filefinder.Close();
return 0;
}

程序编译运行后,仅进行文件名查找时经测试速度比Windows自带的查找程序稍快(Win9x的查找程序是独立的,而Win2000下是集成在Explorer中的),当线程数在5-10之间时速度最快,而超过50时速度反而变慢,这就说明了并不是线程越多越好。线程数过多,CPU的大部分开销花在线程间切换上,而且由于没有足够的待查目录,大多数的线程处在等待状态,占用了大量的系统资源,从而使速度变慢。

当进行包含文字的查找时,我用的是KMP匹配算法,但是速度还是比Windows自带查找程序慢,不知它的原理是什么,还希望知道的朋友告知!

本例只是多线程应用的一个极简单的例子,未免贻笑大方,笔者接触多线程编程时间不长,其中的不妥之处,还请大家指正,欢迎与我联系:jruv@163.com

程序在Win2000,VC++6.0通过。

上一页  1 2 

Tags:一个 线程 实现

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接