std :: async из std :: async в Windows XP - PullRequest
       65

std :: async из std :: async в Windows XP

0 голосов
/ 10 октября 2018

В этом примере печатаются все 2 сообщения под windows7 и ideone.com, но не удается напечатать второе сообщение на windows xp.Что я делаю не так?Если это ошибка, где я должен сообщить об этом?

Скомпилировано для Windows XP с использованием Visual Studio 2017, набор инструментов платформы v141_xp.

#include <iostream>
#include <future>
#include <thread>

using namespace std;
int main()
{
    auto f1 = async(launch::async, []()->int {
        cout << "in outer async" << endl;

         auto f2 = async(launch::async, []()->int {
             cout << "in inner async" << endl;
             return 2;
         });
         f2.get();

        return 1;
    });
    f1.get();

    return 0;
}

UPD при использовании std :: thread вместо std :: async для внутренней функции - хорошо работает на обоихsystems

auto f2 = thread([]()->int {
    cout << "in inner async" << endl;
    return 2;
});
f2.join();

UPD2

Visual Studio 2017 cl.exe версия 19.14.26428 Набор инструментов v141_xp

командная строка:

/permissive- /Yu"stdafx.h" /GS /GL /analyze- /Wall /Gy /Zc:wchar_t /Zi /Gm- /O2 /sdl /Fd"Release\vc141.pdb" /Zc:inline /fp:precise /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_USING_V110_SDK71_" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oy- /Oi /MD /std:c++17 /FC /Fa"Release\" /EHsc /nologo /Fo"Release\" /Fp"Release\testasync.pch" /diagnostics:classic 

UPD3 выглядит как запуск:: async игнорируется при использовании на windows xp

vector<future<void>> v;
for( int i = 0; i < 10; i++ )
    v.push_back(async(launch::async, []() {cout << "thread" << endl; this_thread::sleep_for(5s); }));
for( auto &f : v )
    f.get();

на windows7, это занимает ~ 6 секунд, на windows xp ~ 50 секунд

1 Ответ

0 голосов
/ 10 октября 2018

В Windows std::async(...) располагается поверх пула потоков.Так что могут быть тупики.Внутри f1 вы запускаете новое задание и вызываете f2.get(), который блокируется до завершения f2.Но если auto f2 = async(...) выбрал тот же поток, в котором работает f1, то у вас тупик, и ваша программа не должна завершиться.Если это так, то это не так.

ОБНОВЛЕНИЕ

Пожалуйста, прочитайте о реализации Microsoft std::async здесь .В нем говорится:

Стандарт C ++ гласит, что если policy является launch :: async, функция создает новый поток.Однако реализация Microsoft в настоящее время не соответствует требованиям.Он получает свои потоки из Windows ThreadPool, который в некоторых случаях может предоставлять переработанный поток, а не новый.Это означает, что политика launch :: async фактически реализована как launch :: async | launch :: deferred

Существует еще один ответ , который раскрывает определенную особенность Microsoft std::async реализация:

  • Ограничивает общее количество используемых фоновых потоков, после чего вызов std :: async будет блокироваться, пока поток не станет свободным.На моей машине это число 768.

Итак, я предполагаю, что если у вас есть только один поток в ThreadPool, то вызов std::async изнутри задачи будет тупиковым.Вероятно, это ваш случай, принимая во внимание ваш UPD3 .

Я действительно рекомендую прочитать упомянутый ответ , чтобы вы могли понять, почему Microsoft std::async отличаетсяи как правильно его использовать.

...