cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
89 stars 0 forks source link

Проблемы при использовании сопрограмм #230

Open apolukhin opened 3 years ago

apolukhin commented 3 years ago

Перенос предложения: голоса +4, -0 Автор идеи: grigory.demchenko

В новом стандарте планируется использовать stackless сопрограммы. Проблема с ними в том, что они заставляют использовать ключевое co_async, изменяя возвращаемый тип с T на future. Однако не у всех методов есть возвращаемые типы. Например, нельзя в конструкторе и деструкторе объектов вызывать co_await, т.к. комплятор не может вызывать асинхронно конструктор и деструктор. Такие действия бывают полезны для RAII объектов типа unique_lock, portal и др.

void synchronized()
{
    std::unique_lock<async_mutex> lock;
    myAction();
}
apolukhin commented 3 years ago

yndx-antoshkka, 5 октября 2017, 13:16 Обсудили голосом, заметки чтобы мне не забыть что к чему:

Со stackfull корутинами можно написать код

void synchronized()
{
    schedule lock(writer_thread); // перескакиваем в специальный поток writer_thread
    myAction1(); // выполнится в потоке writer_thread
    myAction2(); // выполнится в потоке writer_thread
    // ~ schedule вернёт нас в изначальный поток
}

со stackless корутинами, так не получится, так как все корутинные методы должны возвращать future. Ближайший аналог

future_t<void> synchronized()
{
    try {
        schedule lock(writer_thread); // через thread_local выставляем что надо выполняться в writer_thread
        co_yield; // считываем thread_local и перескакиваем в поток writer_thread
        myAction1(); // выполнится в потоке writer_thread
        myAction2(); // выполнится в потоке writer_thread
        // ~ schedule через thread_local выставляем что надо выполняться в изначальном потоке
    } catch (...) {}
    co_yield; // считываем thread_local и перескакиваем в изначальный поток
}

При этом возникают проблемы с thread_local, так как мы можем проснуться в другом потоке - необходимо дополнительно сбрасывать thread_local в дефолт при co_yield

Дополнительные проблемы: