在多个驱动器的迭代期间访问冲突

时间:2014-02-21 06:08:06

标签: c++ multithreading winapi vector

我正在一个项目中工作,我必须迭代一组驱动器作为输入来列出它中存在的文件。我用windows线程实现它并将这组文件存储在一个向量中。它工作得很好如果我将一个驱动器作为输入。但是当尝试迭代多个驱动器时,它会在ListTest.exe中显示“0x5efaad4a(msvcp100d.dll)的未处理异常:0xC0000005:访问冲突读取位置0xdddddde1。”我尝试调试程序,但错误出现在我的程序中的随机位置。我真的不知道我的程序中的错误在哪里,因为它适用于单个驱动器。

MultiDrive List.h

#include <string>
#include <iostream>
#include <Windows.h>
#include <vector>




namespace DriveFiles
{
    struct List
    {
         //std::string *scr ;
         std::vector<std::string>files[10];
    };  

    class FileList
    {
        //static const int MAX_THREADS = 3 ;
    public:
        //static vector<std::string>fil;
        //struct List *list;
        static void ListFiles(std::string DriveId);
        static DWORD WINAPI ParThread(LPVOID s);
        static DWORD WINAPI Listing(LPVOID s);
        //static void display(std::vector<std::string>&files);
    };
} 

MultiDriveListing.cpp

#include <iostream>
#include <Windows.h>
#include <fstream>
#include <sstream>
#include <vector>
#include <deque>
#include <sstream>
#include <string>
#include "MultiDrive List.h"

using namespace std;
CRITICAL_SECTION QueueLock;
CRITICAL_SECTION StoreLock;
//CRITICAL_SECTION FileLock;
#define MAX_THREADS 2
HANDLE Child[MAX_THREADS];
deque<string>directories;
//vector<string>files;
int Files = 0;
struct DriveFiles::List *list = new struct DriveFiles::List();

namespace DriveFiles
{

        void FileList :: ListFiles(string DriveId)
        {   
            DWORD threadid; 
            vector<string> v; 
            string buf; 


            stringstream ss(DriveId); 
            //InitializeCriticalSection(&FileLock);
            InitializeCriticalSection(&QueueLock);
            InitializeCriticalSection(&StoreLock);

            cout << " List Will be in file form in few Sec " << endl;

            directories.clear();
            list->files[0].clear();
             while (ss >> buf)
                v.push_back(buf);
            HANDLE *Parent = new HANDLE[v.size()];
            string *scr;
            scr = new string[v.size()];
            //list->scr = new string[v.size()];
            for(int i=0; i<v.size(); i++)
            {
                scr[i]= v[i];
            }
            //cout << "no of drives "<<v.size();
            //list = HeapAlloc(GetProcessHeap(),0,sizeof(List));
            long t1 = GetTickCount();
            for(int i=0;i<v.size();i++)
            {
                 Parent[i] = CreateThread(NULL,0,ParThread,(LPVOID)scr[i].c_str(),0,&threadid);
            }
            WaitForMultipleObjects(v.size(),Parent,TRUE,INFINITE);
            //display();
            cout<< "Execution Time " <<GetTickCount()-t1;
            v.clear();
            //return files;
        }


        DWORD WINAPI FileList :: ParThread(LPVOID s)
        {
            DWORD threadid;
            WIN32_FIND_DATAA ffd;
            //cout << "in parent" <<endl;
             //struct List *x;

            char *drive =(char*)s;
            string path = drive;
            cout<<drive;
            //vector<string>fil;
            //list->files[0] = fil;
            string spec = path + "\\" + "*";

            HANDLE hFind = FindFirstFileA(spec.c_str(), &ffd);

             if (INVALID_HANDLE_VALUE == hFind) 
             {
                     cout << "FindFirstFile error";
             }
                //cout<<"List of Folders in Drive"<<endl;
            do
            {
                 if(!strcmp(ffd.cFileName, "..") == 0 && !strcmp(ffd.cFileName, ".") == 0)
                {
                    if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
                    {   
                        EnterCriticalSection(&QueueLock);
                         directories.push_back( path + "\\" + ffd.cFileName );
                         LeaveCriticalSection(&QueueLock);
                         //cout << ffd.cFileName <<endl;
                    }
                    else
                    {
                        EnterCriticalSection(&StoreLock);
                        list->files[0].push_back( path + "\\" + ffd.cFileName );
                        Files++;
                        LeaveCriticalSection(&StoreLock);
                    }


                 }
            }while (FindNextFileA(hFind, &ffd) != 0);
            FindClose(hFind);
            /*fstream out;
            EnterCriticalSection(&FileLock);
            out.open("List.txt",ios_base::out | ios_base::app );
            vector<string>::iterator it = fil.begin();
            if(fil.size()!=0)
            do
            {
                //cout << "Writing to .txt File ";
                out<<*it<<endl;
                *it++;
            }while(it!=fil.end());
            out.close();
            fil.clear();
            LeaveCriticalSection(&FileLock);*/
            //DeleteCriticalSection(&QueueLock);
            //cout << endl<<list->files[0].size();
            cout << endl<<"No of Files "<<Files;
            for(int i=0;i<MAX_THREADS;i++)
            {
                 Child[i] = CreateThread(NULL,0,Listing,(LPVOID)&list->files[i],0,&threadid);
                 //cout<<endl<<list->files[i+1].size();
                 if( Child[i] == NULL )
                 {
                    printf("CreateThread error: %d\n", GetLastError());
                     return 0;
                 }
            }

             WaitForMultipleObjects(MAX_THREADS,Child,TRUE,INFINITE);
             return 0;
        }
        DWORD WINAPI FileList :: Listing(LPVOID s)
        {

            deque<string>subdir;

            string path = " ";
            string spec = " ";
            string subpath = " ";
            int Files = 0;
            //vector<string>files;
            vector<string>*file;

            file = (vector<string>*)s;
            WIN32_FIND_DATAA ffd;
            //InitializeCriticalSection(&QueueLock);


            while(true)     
            {
                        EnterCriticalSection(&QueueLock);
                        if(directories.empty())
                        {
                            LeaveCriticalSection(&QueueLock);
                            //Sleep(500);
                            break;
                    }
                        else
                        {
                            path = directories.front();
                            directories.pop_front();
                            spec = path + "\\" + "*";
                            LeaveCriticalSection(&QueueLock);
                            subdir.push_front(path);
                        }
                        while(!subdir.empty())
                        {
                            subpath = subdir.front();
                            spec = subpath + "\\" + "*";
                            subdir.pop_front();

                            HANDLE hfind = FindFirstFileA(spec.c_str(),&ffd);
                            if(hfind == INVALID_HANDLE_VALUE)
                                    continue;
                            cout << subpath << endl;
                            do
                            {
                                if(strcmp(ffd.cFileName,".") && strcmp(ffd.cFileName,".."))
                                {
                                    if(ffd.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)
                                    {
                                        //EnterCriticalSection(&QueueLock);
                                        subdir.push_front(subpath + "\\" + ffd.cFileName);
                                        //LeaveCriticalSection(&QueueLock);
                                    }
                                    else
                                    {   
                                        //EnterCriticalSection(&StoreLock);
                                        file->push_back(subpath + "\\" + ffd.cFileName);
                                        Files++;
                                        //LeaveCriticalSection(&StoreLock);
                                    }
                            }
                        }while(FindNextFileA(hfind,&ffd));
                        FindClose(hfind);
                        hfind = INVALID_HANDLE_VALUE;
                    }
            }
            //subdir.clear();
            //directories.clear();
            //cout <<endl<<file->size();
            cout<<" No of Files  "<<Files <<endl ;
            //display(files);
            //subdir.clear();
            //HeapFree(GetProcessHeap(), 0, list);
            return 0;
        }
}

TestList.cpp

#include <iostream>
#include <string>
#include <fstream>
#include "MultiDrive List.h"

using namespace std;
using namespace DriveFiles;

int main()
{
    string drv;

    //vector<string>files;
    ofstream out;
    //List *list;

    cout << "\n Enter the Id of Drives to list " <<endl;

    getline(cin,drv);

    FileList :: ListFiles(drv);

    extern struct DriveFiles::List *list;

    /*for(int i=0;i<3;i++)
        cout <<endl<< list->files[i].size();*/

    //cout<<"Listed";

    for(int i=0;i<3;i++)
    {

        //while(k< list->files[i].size())
        //{
        //cout <<endl<< list->files[i].size();
            out.open("Lists.txt",ios_base::out | ios_base::app );
            vector<string>::iterator it = list->files[i].begin();
            if(list->files[i].size()!=0)
            do
            {
                //cout << "Writing to .txt File ";
                out<<*it<<endl;
                *it++;
                //k++;
            }while(it!=list->files[i].end());
            out.close();
        //}
        //list->files[i].clear();
    }
    system("pause");
    return 0;
}

我的代码只要MultiDrive List.h和MultiDriveListing.cpp来自静态.lib库.TestList.cpp是访问库以获取输出并打印它的程序。请进行任何改进和帮助是欢迎。

2 个答案:

答案 0 :(得分:0)

虽然您的代码存在一些问题(泄漏是其中之一),但快速查看会让我怀疑此代码块中的迭代器增量。请尝试以下更改:

do
{
    out<<*it<<endl;
    ++it;          // <----- this line changed
}while(it!=list->files[i].end());

答案 1 :(得分:0)

我怀疑是

的用法
(char*)s


跨越多个线程。