在多线程中访问变量的问题

问题描述 投票:0回答:0

有一个任务需要递归重命名特定的目录文件。每个目录都由一个单独的线程处理。但是 Shiftfile 变量有问题。尝试访问多个线程时,发生异常。我试图用互斥体来解决问题,但结果是。你能告诉我怎么了吗?

#include <windows.h>
#include <iostream>
#include <tchar.h>
#include <mutex>

using namespace std;

std::mutex g_mutex;

void outputERROR() {
    LPVOID lpMsgBuf;
    DWORD dw = GetLastError();
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
    wcout << (TCHAR*)lpMsgBuf << endl;
    return;
}

void MoveFileNames(const TCHAR* directory, int* Shiftfile, std::mutex& mutex)

{
    WIN32_FIND_DATA ffd;
    HANDLE hFind = INVALID_HANDLE_VALUE;
    TCHAR searchPath[MAX_PATH];
    _stprintf_s(searchPath, _T("%s\\*"), directory);

    hFind = FindFirstFile(searchPath, &ffd);

    if (hFind == INVALID_HANDLE_VALUE)
    {
        cout << "Invalid path!" << endl;
        outputERROR();
        return;
    }

    while (FindNextFile(hFind, &ffd) != 0)
    {
        if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            if (_tcscmp(ffd.cFileName, _T(".")) == 0 || _tcscmp(ffd.cFileName, _T("..")) == 0)
                continue;

            TCHAR subdir[MAX_PATH];
            _stprintf_s(subdir, _T("%s\\%s"), directory, ffd.cFileName);

            DWORD threadId;
            HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MoveFileNames, (LPVOID)subdir, 0, &threadId);

            if (hThread == NULL)
            {
                cout << "Error creating thread!" << endl;
                outputERROR();
            }
            else
            {
                WaitForSingleObject(hThread, INFINITE);
                if (!CloseHandle(hThread))
                {
                    cout << "Error closing thread handle!" << endl;
                    outputERROR();
                }
            }
        }
        else
        {
            if (_tcslen(ffd.cFileName) % 2 == 1)
            {
                if (_tcsstr(ffd.cFileName, _T("!")) == nullptr)
                {
                    TCHAR newFileName[MAX_PATH], sourceFile[MAX_PATH];
                    _stprintf_s(newFileName, _T("%s\\!%s"), directory, ffd.cFileName);
                    _stprintf_s(sourceFile, _T("%s\\%s"), directory, ffd.cFileName);

                    if (!MoveFile(sourceFile, newFileName))
                    {
                        cout << "Renaming error!" << endl;
                        outputERROR();
                    }
                    else
                    {
                        std::lock_guard<std::mutex> lock(mutex);
                        (*Shiftfile)++;
                    }
                }
            }
        }
    }

    if (GetLastError() != ERROR_NO_MORE_FILES)
    {
        cout << "Error!" << endl;
        outputERROR();
    }

    if (FindClose(hFind) == 0)
    {
        cout << "Closing error!" << endl;
        outputERROR();
    }

    return;
}

int main()
{
    int Shiftfile = 0;
    setlocale(LC_ALL, "ru");
    TCHAR directory[] = _T("C:\\Калькулятор");

    MoveFileNames(directory, &Shiftfile, g_mutex);

    if (Shiftfile == 0) {

        cout << "No files to rename!" << endl;
    }
    else
    {
        cout << ((Shiftfile > 1) ? "The program has changed the files!" : "The program rewrote the file!") << endl;
    }

    return 0;
}
c++ multithreading stream
© www.soinside.com 2019 - 2024. All rights reserved.