簡體   English   中英

當我向線程分配承諾時,C ++收到“調試錯誤R6010 -abort()已被調用”

[英]C++ Getting “Debug Error R6010 -abort() has been called ” when i assign promises to threads

我收到錯誤消息: 調試錯誤R6010 -abort()已被調用

在我的代碼中:

bool ListFiles(wstring path, wstring mask, vector<wstring>& files) {
HANDLE hFind = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA ffd;
wstring spec;
stack<wstring> directories;

directories.push(path);
files.clear();

while (!directories.empty()) {
    path = directories.top();
    spec = path + L"\\" + mask;
    directories.pop();

    hFind = FindFirstFile(spec.c_str(), &ffd);
    if (hFind == INVALID_HANDLE_VALUE)  {
        return false;
    }

    do {
        if (wcscmp(ffd.cFileName, L".") != 0 && wcscmp(ffd.cFileName, L"..") != 0) {
            if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                directories.push(path + L"/" + ffd.cFileName);
            }
            else {
                files.push_back(path + L"/" + ffd.cFileName);
            }
        }
    } while (FindNextFile(hFind, &ffd) != 0);

    if (GetLastError() != ERROR_NO_MORE_FILES) {
        FindClose(hFind);
        return false;
    }

    FindClose(hFind);
    hFind = INVALID_HANDLE_VALUE;
}

return true;}

void findText(std::string filename, std::string word , promise<string> &prom) {
std::ifstream f(filename);
std::string s;
std::string notFound = "no";
bool found = false;
if (!f) {
    std::cout << "il file non esiste"<<std::endl;
}
while (f.good()) {
        std::getline(f, s);
        if (s.find(word, 0) != string::npos) {
            found = true;
        }

    }
if (found) {

    //cout << "Parola trovata in -> " << filename << endl;
    prom.set_value_at_thread_exit(filename);
}
else {
    prom.set_value_at_thread_exit(notFound);
}

f.close();}
int main(int argc, char* argv[]){
//vector<std::thread> th;
vector<future<string>> futures;
vector<wstring> files;
string search = "ciao";
string notFound = "no";
if (ListFiles(L"pds", L"*", files)) {

    for (vector<wstring>::iterator it = files.begin(); it != files.end(); ++it) {
        //wcout << it->c_str() << endl;
        wstring ws(it->c_str());
        string str(ws.begin(), ws.end());
        // Show String
        //cout << str << endl;
        //Creo una promise per ogni thread in cui andrò a cercare il risulato
        std::promise<string> prom;
        futures.push_back(prom.get_future());
        std::thread(findText,str,search,std::ref(prom)).detach();

    }
}   

for (int i = 0; i < futures.size(); i++){
    futures.at(i).wait();
    if (futures.at(i).get().compare(notFound)!=0)
    cout << "Parola trovata in ->" <<futures.at(i).get()<<endl;
}
return 0;}

我曾經嘗試過不使用promise,並且如果發現word並起作用的話,使每個線程打印文件名。 所以我不知道為什么使用諾言和未來來找回這個價值會導致我這個問題...我正在使用VS 2013

讓我們仔細看一下這些行:

for (...) {
    ...
    std::promise<string> prom;
    ...
    std::thread(findText,str,search,std::ref(prom)).detach();
}

首先,創建一個局部變量prom ,然后將對該變量的引用傳遞給線程。

問題在於,一旦循環迭代,變量prom就會超出范圍,並且對象將被破壞。 您曾經沒有的引用不再具有引用的內容。 使用引用將導致不確定的行為

因此解決方案是不使用引用(或指向prom變量的指針),這會導致問題,因為無法復制std::promise 但是,可以將其移動:

std::thread(findText,str,search,std::move(prom)).detach();

為此,您可能需要使線程函數將promise參數用作右值引用:

void findText(std::string filename, std::string word , promise<string> &&prom) {
    ...
}

如果上述解決方案不起作用,則可以使用新的C ++ 11智能指針(如std::unique_ptr使用動態分配。

然后線程函數應按值獲取智能指針,例如

void findText(std::string filename, std::string word , std::unique_ptr<std::promise<string>> prom) {
    ...
}

然后創建像

auto prom = std::make_unique<std::promise<std::string>>();
// Or if you don't have std::make_unique
//   std::unique_ptr<std::promise<std::string>> prom(new std::promise<std::string>);
futures.push_back(prom->get_future();
std::thread(findText,str,search,std::move(prom)).detach();

請記住,在線程函數( findText )中,變量prom是一個指針,並且在使用它時需要使用箭頭運算符,例如

prom->set_value_at_thread_exit(filename);
//  ^^
// Note "arrow" operator here

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM