【发布时间】:2014-01-20 10:34:19
【问题描述】:
我编写了一个将目录作为输入并在其中输出文件列表的代码。我在单线程中实现了它。为了使用多线程实现该怎么做?给我逻辑或代码。
平台:Windows API:Windows.h 语言:c++
#include <iostream>
#include <Windows.h>
#include <queue>
#include <TlHelp32.h>
#include <string>
#include <vector>
using namespace std;
#define MAX_THREADS 1
int Files = 0;
vector<string>files;
vector<string> ListContents(string path,vector<string>&files)
{
HANDLE hfind = INVALID_HANDLE_VALUE;
WIN32_FIND_DATAA ffd;
string spec;
wstring ws;
deque<string> directories;
directories.push_back(path);
files.clear();
while(!directories.empty())
{
path = directories.back();
spec = path + "\\" + "*";
directories.pop_back();
std::wstring wspec( spec.begin(),spec.end());
ws = wspec;
hfind = FindFirstFileA(spec.c_str(),&ffd);
if(hfind == INVALID_HANDLE_VALUE)
continue;
//return false;
do
{
if(strcmp(ffd.cFileName,".") && strcmp(ffd.cFileName,".."))
{
if(ffd.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)
{
directories.push_back(path + "\\" + ffd.cFileName );
}
else
{
//cout<<"Current File is "<<ffd.cFileName<<endl;
files.push_back(path + "\\" + ffd.cFileName);
Files++;
}
}
}while(FindNextFileA(hfind,&ffd)!=0);
if (GetLastError() != ERROR_NO_MORE_FILES) {
FindClose(hfind);
ExitProcess(4);
//return false;
}
FindClose(hfind);
hfind = INVALID_HANDLE_VALUE;
}
//return true;
return files;
}
void display(vector<string>&files)
{
vector<string>::iterator iter = files.begin();
if(files.size()!=0)
do
{
cout<<*iter<<endl;
*iter++;
}while(iter!=files.end());
}
DWORD WINAPI MyThread1(LPVOID s)
{
char* ss = (char*)s;
string path(ss);
//vector<string> files;
files = ListContents(path,files);
//display(files);
return 0;
}
int main(int argc,char *argv[])
{
DWORD threadid;
int newent = 0;
int newex = 0;
FILETIME creation,exit,kernel,user;
SYSTEMTIME st1,st2;
THREADENTRY32 entry;
char szEntrytime[255],szExittime[255];
//vector<string> files;
Sem = CreateSemaphore(NULL,MAX_SEM_COUNT,MAX_SEM_COUNT,NULL);
for(int i= 0;i<MAX_THREADS;i++)
{
hthread[i] = CreateThread(NULL,0,List,NULL,0,&threadid);
if( hthread[i] == NULL )
{
printf("CreateThread error: %d\n", GetLastError());
return 1;
}
}
HANDLE hsnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);
if(hthread)
{
WaitForMultipleObjects(MAX_THREADS,&hthread,TRUE,INFINITE);
if(GetThreadTimes(hthread,&creation,&exit,&kernel,&user)==0)
{
cout<<"can't able to get thrad timings";
ExitProcess(3);
}
else
{
GetThreadTimes(hthread,&creation,&exit,&kernel,&user);
FileTimeToLocalFileTime(&creation,&creation);
FileTimeToLocalFileTime(&exit,&exit);
FileTimeToSystemTime(&creation,&st1);
FileTimeToSystemTime(&exit,&st2);
}
}
GetTimeFormatA( LOCALE_USER_DEFAULT, 0, &st1, NULL, szEntrytime, 255 );
GetTimeFormatA( LOCALE_USER_DEFAULT, 0, &st2, NULL, szExittime, 255 );
printf( "Thread Entry Time %s\n", szEntrytime );
printf( "Thread Exit Time %s\n", szExittime );
//files = ListContents(argv[1],files);
cout<<" No of Files "<<Files <<endl ;
CloseHandle(hthread);
display(files);
/*if(ListContents(argv[1],files))
{
}*/
system("pause");
return 0;
}
【问题讨论】:
-
更好的方法是将
boost::filesystem::directory_iterator和英特尔的tbb::parallel_for_each结合起来。 -
我试过了,但是 boost 文件系统是预先包含在 linux 中的。对于 Windows,我需要越来越多的依赖文件。我需要一个解决方案来在 windows 平台上实现它,而不是跨平台。
-
祝你好运; windows API 应被视为不应直接调用的低级 API。也及时 boost.filesystem 将成为 std.filesystem。您可以使用 MS 并行模式库而不是 intel tbb。
标签: c++ multithreading winapi