多线程搜索系统盘文件

说明:
1.利用线程进行文件扫描。每遇到一个文件夹,创建一条线程进去搜索文件。(与递归类似)


注意点:
1.vector容器不安全。要设置临界区,不会多条线程同时对vector进行操作,实现同步。(原子操作)
2.具体步骤。
//临界区
CRITICAL_SECTION g_cs;
//初始化
InitializeCriticalSection(&g_cs);
//上锁
EnterCriticalSection(&g_cs);
//解锁
LeaveCriticalSection(&g_cs);
//释放
DeleteCriticalSection(&g_cs);

3.对线程进行计数。
加数
InterlockedAdd(&g_lThreadNum, 1);
减数
InterlockedAdd(&g_lThreadNum, -1);


4.设置多线程退出标识。HANDLE g_hExitEvent; //信号量。标记线程退出
因为是多线程进行操作,要保证线程全部退出后,主线程才退出,程序结束。

//创建事件消息
g_hExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
//如果全部线程退出,激活该信号量
SetEvent(&g_hExitEvent);

//只需等待信号量,即退出程序,不需要使用WaitForMultiObject(),会造成长时间等待、阻塞。
WaitForSingleObject(g_hExitEvent, INFINITE);

5.对容器进行释放
for (auto g_h_Threads: g_hThreads)
{
CloseHandle(g_h_Threads);
}

源代码:

#include "stdafx.h"
#include <Windows.h>
#include <stdlib.h>
#include <iostream>
using namespace  std;
#include <process.h>
#include <vector>

vector<HANDLE> g_hThreads;    //存放线程的句柄
long g_lNum = 0;        //文件数目
long g_lFileNum=0;        //文件夹数目
long g_lThreadNum = 0;        //线程数目
HANDLE g_hExitEvent;        //标记线程退出
CRITICAL_SECTION g_cs;        //临界区

struct ThreadData
{
    wstring m_strBeginFileName;
    wstring m_strSearchFileName;
    wstring m_strFilte;
};

//文件路径标准化 "C:\\"
wstring MakeStdName(wstring &wstrFileName)
{
    if (wstrFileName.back() != '\\')
    {
        return (wstrFileName + L"\\");
    }
    else
        return  wstrFileName;

}


unsigned  _stdcall  FindFileThread(void * lParam)
{
    ThreadData *pData = (ThreadData *)lParam;
    WIN32_FIND_DATAW FileData = {0};
    HANDLE hFindFile = FindFirstFileW((MakeStdName(pData->m_strBeginFileName) + (pData->m_strFilte)).c_str(),&FileData);
    
    //可能打开文件失败,但是下面依然创建线程。
    if (hFindFile != INVALID_HANDLE_VALUE)
    {

        do
        {
            if (FileData.cFileName, L"." == 0)
                continue;
            if (FileData.cFileName, L".." == 0)
                continue;

            if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                ThreadData *pTempData = new ThreadData;
                pTempData->m_strBeginFileName =MakeStdName(pData->m_strBeginFileName) + FileData.cFileName;
                pTempData->m_strFilte = pData->m_strFilte;
                pTempData->m_strSearchFileName = pData->m_strSearchFileName;

                //上锁
                EnterCriticalSection(&g_cs);

                InterlockedAdd(&g_lThreadNum, 1);
                g_hThreads.push_back((HANDLE)_beginthreadex(NULL, 0, FindFileThread, pTempData, 0, NULL));
                
                
                //解锁
                LeaveCriticalSection(&g_cs);
            }
            else
            {
                if (wcsstr(FileData.cFileName, pData->m_strSearchFileName.c_str()) != NULL)
                {
                    printf("文件:%ls\r\n", (MakeStdName(pData->m_strBeginFileName) + FileData.cFileName).c_str());
                    InterlockedAdd(&g_lNum, 1);
                }
            }

        } while (FindNextFileW(hFindFile, &FileData));
    }
    delete pData;
    InterlockedAdd(&g_lThreadNum, -1);
    if (g_lThreadNum == 0)
    {
        SetEvent(&g_hExitEvent);
    }
    return g_lNum;
}


int _tmain(int argc, _TCHAR* argv[])
{

    DWORD dwBeginTime = GetTickCount();
    
    InitializeCriticalSection(&g_cs);
    
    g_hExitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    ThreadData *pTempData = new ThreadData;
    pTempData->m_strBeginFileName = L"C:\\";
    pTempData->m_strFilte = L"*.*";
    pTempData->m_strSearchFileName = L"ntdll";

    InterlockedAdd(&g_lThreadNum, 1);
    g_hThreads.push_back((HANDLE)_beginthreadex(NULL, 0, FindFileThread, pTempData, 0, NULL));

    WaitForSingleObject(g_hExitEvent, INFINITE);
    //for (auto g_h_Threads: g_hThreads)
    //{
    //    CloseHandle(g_h_Threads);
    //}
    DeleteCriticalSection(&g_cs);
    DWORD dwTime = GetTickCount() - dwBeginTime;

    _endthread();
    printf("文件夹个数:%d,ntdll文件个数: %d\r\n", g_lFileNum, g_lNum);
    printf("共用%d秒\r\n", dwTime / 1000);
    system("pause");
    return 0;
}

 

posted @ 2017-09-25 12:01  gd_沐辰  阅读(538)  评论(0编辑  收藏  举报