다른 스레드의 데이터를 XML 파일에 쓰는 앱을 작성하고 있습니다. 내가 이벤트 코어 개체를 사용하여 동기화하려고하지만 파일에서 잘못된 데이터가 발생합니다. 나는 다음 결과를다른 스레드의 동기화 출력 스트림
<file path="somePath" />
<file path="somePath" <file path="somePath" /> />....
얻을하지만 난
<file path="somePath" />
<file path="somePath" />
<file path="somePath" />
내 의사 코드 아래 참조 얻을 것으로 기대합니다. 뭐가 잘못 됐어?
unsigned int WINAPI MyThread(void *p)
{
std::wofstream outstr;
outstr.open("indexingtest.xml", std::ios::app);
do
{
if(somePredicat1)
{
WaitForSingleObject(hEvent, INFINITE);
outstr <<"<file path=\""<< sFileName << "\"\n";
outstr <<"\tsize=\""<< fileSize << "\" />\n";
ReleaseMutex(hMutex);
}
if(somePredicat3)
{
MyThread(sFileName);
}
}while(somePredicat2);
outstr.close();
FindClose(hSearch);
return 0;
}
int _tmain(int argc, TCHAR *argv[])
{
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
//hMutex = CreateMutex(NULL, FALSE, 0);
unsigned int ThreadID;
HANDLE hThread1 = (HANDLE)_beginthreadex(NULL, 0, MyThread, L"D:\\*", 0, &ThreadID);
HANDLE hThread2 = (HANDLE)_beginthreadex(NULL, 0, MyThread, L"C:\\*", 0, &ThreadID);
SetEvent(hEvent);
std::wcout << "\a" << std::endl;
WaitForSingleObject(hThread1, INFINITE);
return 0;
}
더 구체적인 코드
HANDLE hMutex = CreateMutex(NULL,FALSE, 0);
wchar_t** GetAllFilesImpl(wchar_t const* folder, wchar_t** res, size_t* pAllocated, size_t* pUsed)
{
HANDLE hSearch;
WIN32_FIND_DATAW fileinfo;
size_t allocatedMemory = 0;
hSearch = FindFirstFileW(folder, &fileinfo);
if(hSearch != INVALID_HANDLE_VALUE) {
do {
wchar_t* sFileName, ** tmp, sTmp[ 1024 ];
long fileSize = 0;
long creationDate;
/* ignore ., .. */
if(!wcscmp(fileinfo.cFileName, L".") ||
!wcscmp(fileinfo.cFileName, L".."))
continue;
sFileName = PathCreator(folder, fileinfo.cFileName);
fileSize = fileinfo.nFileSizeLow;
creationDate = fileinfo.ftCreationTime.dwHighDateTime;
if(fileSize)
{
WaitForSingleObject(hMutex, INFINITE);
std::wofstream outstr;
outstr.open("indexingtest.xml", std::ios::app);
outstr.seekp(std::ios_base::end);
outstr <<"<file path=\""<< sFileName << "\"\n";
outstr <<"\tsize=\""<< fileSize << "\" />\n";
outstr.seekp(std::ios_base::end);
outstr.close();
wprintf(L"%s\n", sFileName);
ReleaseMutex(hMutex);
}
tmp = AddToArray(res, pAllocated, pUsed, sFileName);
if(!tmp) return FreeAllFilesMemory(res), NULL;
res = tmp;
if(fileinfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
wcscpy_s(sTmp, sFileName);
wcscat_s(sTmp, L"\\*");
tmp = GetAllFilesImpl(sTmp, res, pAllocated, pUsed);
if(!tmp) return NULL;
res = tmp;
}
} while(FindNextFileW(hSearch, &fileinfo));
FindClose(hSearch);
}
return res;
}
unsigned int WINAPI GetAllFiles(void* folder)
{
size_t nAllocated = 0, nUsed = 0;
wchar_t** res = GetAllFilesImpl((wchar_t *)folder, NULL, &nAllocated, &nUsed);
if(res) {
/* to indicate end of result add a NULL string */
wchar_t** tmp = AddToArray(res, &nAllocated, &nUsed, NULL);
if(!tmp) return FreeAllFilesMemory(res), -1;
res = tmp;
}
std::wcout << "\a" << std::endl;
return 0;
}
int _tmain(int argc, TCHAR *argv[])
{
Sleep(1000);
unsigned int ThreadID;
HANDLE hThreads[3];
hThreads[0] = (HANDLE)_beginthreadex(NULL, 0, GetAllFiles, L"D:\\*", 0, &ThreadID);
hThreads[1] = (HANDLE)_beginthreadex(NULL, 0, GetAllFiles, L"C:\\Users\\Andrew\\Desktop\\*", 0, &ThreadID);
hThreads[2] = (HANDLE)_beginthreadex(NULL, 0, GetAllFiles, L"E:\\*", 0, &ThreadID);
unsigned int dw = WaitForMultipleObjects(3, hThreads, TRUE, INFINITE);
CloseHandle(hFile);
printf("finished\n");
return 0;
}
이렇게하면 모든 데이터가 파일에 혼란스러워지는 것은 아닙니다. 스레드 함수에 재귀가 있다고 말하는 것을 잊어 버렸습니다. 질문의 판을보십시오. – abilash
O 죄송합니다. 잘못된 문서를 수정했습니다. – abilash