рдХреЛрд░реБрдЯрд┐рди рдХреЗ рд╕рд╛рде рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЛрдб рд░реИрдЦрд┐рдХ

рдЫрд╡рд┐

рдЬрдирд░реЗрдЯрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрд░рдЯрд╛рдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рдЙрдиреНрд╣реЗрдВ рдореМрдЬреВрджрд╛ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЛрдб рдХреЛ рд░реИрдЦрд┐рдХ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЪрд▓реЛ рдПрдХ рдЫреЛрдЯреЗ рд╕реЗ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдРрд╕рд╛ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВред рдЕрднрд┐рдиреЗрддрд╛ рдХреЗ рдврд╛рдВрдЪреЗ рдкрд░ рд▓рд┐рдЦреЗ рдЧрдП рдХреЛрдб рдХреЛ рд▓реЗрдВ рдФрд░ рдЗрд╕ рдХреЛрдб рдХреЗ рдПрдХ рдХрд╛рд░реНрдп рдХреЛ рдХреЛрд░рдЯрд╛рдЗрди рдкрд░ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦреЗрдВред рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдХреЛрд░рдЯрд╛рдЗрдиреНрд╕ рд╢рд╛рдЦрд╛ рд╕реЗ gcc рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ ред

рд╣рдорд╛рд░рд╛ рд▓рдХреНрд╖реНрдп рдиреВрдбрд▓реНрд╕ рд╕реЗ рдХреЙрд▓рдмреИрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реИ:

    abActor.getA(ABActor::GetACallback([this](int a) {
        abActor.getB(ABActor::GetBCallback([a, this](int b) {
            abActor.saveAB(a - b, a + b, ABActor::SaveABCallback([this](){
                abActor.getA(ABActor::GetACallback([this](int a) {
                    abActor.getB(ABActor::GetBCallback([a, this](int b) {
                        std::cout << "Result " << a << " " << b << std::endl;
                    }));
                }));
            }));
        }));
    }));

рдХреА рддрд░рд╣:

const int a = co_await actor.abActor.getAAsync();
const int b = co_await actor.abActor.getBAsync();
co_await actor.abActor.saveABAsync(a - b, a + b);
const int newA = co_await actor.abActor.getAAsync();
const int newB = co_await actor.abActor.getBAsync();
std::cout << "Result " << newA << " " << newB << std::endl;

рддреЛ рдЪрд▓реЛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИред

рдЕрднрд┐рдиреЗрддрд╛


рд╢реБрд░реБрдЖрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЕрднрд┐рдиреЗрддрд╛ рдХреА рд░реВрдкрд░реЗрдЦрд╛ рдмрдирд╛рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред рдПрдХ рдкреВрд░реНрдг рдЕрднрд┐рдиреЗрддрд╛ рдХреА рд░реВрдкрд░реЗрдЦрд╛ рддреИрдпрд╛рд░ рдХрд░рдирд╛ рдПрдХ рдХрдард┐рди рдФрд░ рдмрдбрд╝рд╛ рдХрд╛рдо рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдХреЗрд╡рд▓ рдЗрд╕реЗ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдПрдХ рдЖрдзрд╛рд░ рд╡рд░реНрдЧ рдмрдирд╛рдПрдВ:

class Actor {
public:
    using Task = std::function<void()>;
public:
    virtual ~Actor();
public:
    void addTask(const Task &task);
    void tryRunTask();
private:
    std::queue<Task> queue;
    mutable std::mutex mutex;
};

рдпрд╣ рд╡рд┐рдЪрд╛рд░ рдореВрд▓ рд░реВрдк рд╕реЗ рд╕рд░рд▓ рд╣реИ: рд╣рдо рдРрд╕реЗ рдХрд╛рд░реНрдп рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдПрдХ рдХрддрд╛рд░ рдореЗрдВ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд╕реНрддреБрдПрдВ рд╣реИрдВ, рдФрд░ рдЬрдм рд╣рдо рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЗрд╕ рдХрд╛рд░реНрдп рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред рд╡рд░реНрдЧ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣рдорд╛рд░реЗ рдЗрд░рд╛рджреЛрдВ рдХреА рдкреБрд╖реНрдЯрд┐ рдХрд░рддрд╛ рд╣реИ:

Actor::~Actor() = default;

void Actor::addTask(const Task &task) {
    std::lock_guard lock(mutex);
    queue.push(task);
}

void Actor::tryRunTask() {
    std::unique_lock lock(mutex);
    if (queue.empty()) {
        return;
    }

    const Task task = queue.front();
    queue.pop();
    lock.unlock();

    std::invoke(task);
}

рдЕрдЧрд▓реА рдХрдХреНрд╖рд╛ "рдзрд╛рдЧрд╛" рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╣рдорд╛рд░реЗ рдХрд▓рд╛рдХрд╛рд░ рд╣реЛрдВрдЧреЗ:

class Actor;

class ActorThread {
public:
    ~ActorThread();
public:
    void addActor(Actor &actor);
    void run();
private:
    std::vector<std::reference_wrapper<Actor>> actors;
};

рдпрд╣рд╛рдВ рднреА рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ: рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ, рд╣рдо рдЕрдкрдиреЗ рдПрдХреНрдЯрд░реНрд╕ рдХреЛ addActor рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдзрд╛рдЧреЗ рд╕реЗ "рдмрд╛рдВрдзрддреЗ рд╣реИрдВ", рдФрд░ рдлрд┐рд░ рд╣рдо рд░рди рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдереНрд░реЗрдб рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред

ActorThread::~ActorThread() = default;

void ActorThread::addActor(Actor &actor) {
    actors.emplace_back(actor);
}

void ActorThread::run() {
    while (true) {
        for (Actor &actor: actors) {
            actor.tryRunTask();
        }
    }
}

рдзрд╛рдЧрд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╕рдордп, рд╣рдо рдПрдХ рдЕрдирдВрдд рд▓реВрдк рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдЕрднрд┐рдиреЗрддрд╛ рд╕реЗ рдПрдХ рдХрд╛рд░реНрдп рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВред рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рд▓рд┐рдП рдХрд░реЗрдЧрд╛ред

рдЕрдм рдЖрдЗрдП рдЕрднрд┐рдиреЗрддрд╛ рд╡рд░реНрдЧ рдХреЗ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдХреЛ рджреЗрдЦреЗрдВ:

class ABActor: public Actor {
public:
    using GetACallback = Callback<void(int result)>;
    using GetBCallback = Callback<void(int result)>;
    using SaveABCallback = Callback<void()>;
public:
    void getA(const GetACallback &callback);
    void getB(const GetBCallback &callback);
    void saveAB(int a, int b, const SaveABCallback &callback);
private:
    void getAProcess(const GetACallback &callback);
    void getBProcess(const GetBCallback &callback);
    void saveABProcess(int a, int b, const SaveABCallback &callback);
private:
    int a = 10;
    int b = 20;
};

рдпрд╣ рд╡рд░реНрдЧ рдЕрдкрдиреЗ рдЖрдк рдореЗрдВ 2 рдирдВрдмрд░ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИ - рдП рдФрд░ рдмреА, рдФрд░, рдЕрдиреБрд░реЛрдз рдкрд░, рдЙрдирдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рддрд╛ рд╣реИ рдпрд╛ рдЙрдиреНрд╣реЗрдВ рдЕрдзрд┐рд▓реЗрдЦрд┐рдд рдХрд░рддрд╛ рд╣реИред

рдХреЙрд▓рдмреИрдХ рдХреЗ рд░реВрдк рдореЗрдВ, рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд╕реНрддреБ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЖрдЗрдП рдЗрд╕ рддрдереНрдп рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╡рд┐рднрд┐рдиреНрди рдЕрднрд┐рдиреЗрддрд╛рдУрдВ рдХреЛ рд╡рд┐рднрд┐рдиреНрди рдереНрд░реЗрдбреНрд╕ рдореЗрдВ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдФрд░ рдЗрд╕рд▓рд┐рдП, рдпрджрд┐ рдХрд╛рдо рдХреЗ рдЕрдВрдд рдореЗрдВ рд╣рдо рдХреЙрд▓рдмреИрдХ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдХреЙрд▓рдмреИрдХ рд╡рд░реНрддрдорд╛рди рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдереНрд░реЗрдб рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛, рди рдХрд┐ рдЙрд╕ рдереНрд░реЗрдб рдореЗрдВ рдЬрд┐рд╕рдиреЗ рд╣рдорд╛рд░реЗ рддрд░реАрдХреЗ рдХреЛ рдХреЙрд▓ рдХрд┐рдпрд╛ рдФрд░ рдпрд╣ рдХреЙрд▓рдмреИрдХ рдмрдирд╛рдпрд╛ред рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ рдХреЙрд▓рдмреИрдХ рдкрд░ рдПрдХ рд░реИрдкрд░ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдХреЛ рд╣рд▓ рдХрд░реЗрдЧрд╛:

template<typename C>
class Callback {
public:
    template<typename Functor>
    Callback(Actor &sender, const Functor &callback)
        : sender(sender)
        , callback(callback)
    {}
public:
    template<typename ...Args>
    void operator() (Args&& ...args) const {
        sender.addTask(std::bind(callback, std::forward<Args>(args)...));
    }
private:
    Actor &sender;
    std::function<C> callback;
};

рдпрд╣ рдЖрд╡рд░рдг рдореВрд▓ рдЕрднрд┐рдиреЗрддрд╛ рдХреЛ рдпрд╛рдж рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЬрдм рдЖрдк рдЕрдкрдиреЗ рдЖрдк рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рдореВрд▓ рдЕрднрд┐рдиреЗрддрд╛ рдХреЗ рдХрд╛рд░реНрдп рдХрддрд╛рд░ рдореЗрдВ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХреЙрд▓рдмреИрдХ рдЬреЛрдбрд╝рддрд╛ рд╣реИред
рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, ABActor рд╡рд░реНрдЧ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

void ABActor::getA(const GetACallback &callback) {
    addTask(std::bind(&ABActor::getAProcess, this, callback));
}

void ABActor::getAProcess(const ABActor::GetACallback &callback) {
    std::invoke(callback, a);
}

void ABActor::getB(const GetBCallback &callback) {
    addTask(std::bind(&ABActor::getBProcess, this, callback));
}

void ABActor::getBProcess(const ABActor::GetBCallback &callback) {
    std::invoke(callback, b);
}

void ABActor::saveAB(int a, int b, const SaveABCallback &callback) {
    addTask(std::bind(&ABActor::saveABProcess, this, a, b, callback));
}

void ABActor::saveABProcess(int a, int b, const ABActor::SaveABCallback &callback) {
    this->a = a;
    this->b = b;
    std::invoke(callback);
}

рдХрдХреНрд╖рд╛ рдХреА рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╡рд┐рдзрд┐ рдореЗрдВ, рд╣рдо рдХреЗрд╡рд▓ рдХрдХреНрд╖рд╛ рдХреЗ рд╕рдВрдмрдВрдзрд┐рдд "рд╕реНрд▓реЙрдЯ" рдХреЛ рдкрд╛рд░рд┐рдд рдХрд┐рдП рдЧрдП рддрд░реНрдХреЛрдВ рдХреЛ рдмрд╛рдВрдзрддреЗ рд╣реИрдВ, рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдПрдХ рдХрд╛рд░реНрдп рдмрдирд╛рддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕ рдХрд╛рд░реНрдп рдХреЛ рдЗрд╕ рд╡рд░реНрдЧ рдХреА рдХрд╛рд░реНрдп рдХрддрд╛рд░ рдореЗрдВ рд░рдЦрддреЗ рд╣реИрдВред рдЬрдм рдХрд╛рд░реНрдп рдереНрд░реЗрдб рдХрд╛рд░реНрдп рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рд╕рд╣реА "рд╕реНрд▓реЙрдЯ" рдХреЛ рдХреЙрд▓ рдХрд░реЗрдЧрд╛, рдЬреЛ рдХрд┐ рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХрд░реЗрдЧрд╛ рдЬреЛ рдХреЙрд▓рдмреИрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдФрд░ рдХреЙрд▓рдмреИрдХ рдХрд░реЗрдЧрд╛, рдЬреЛ рдмрджрд▓реЗ рдореЗрдВ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХреЙрд▓рдмреИрдХ рдХреЛ рдЙрд╕ рдХрд╛рд░реНрдп рдХреА рдХрддрд╛рд░ рдореЗрдВ рднреЗрдЬ рджреЗрдЧрд╛ рдЬреЛ рдЗрд╕рдХреЗ рдХрд╛рд░рдг рд╣реБрдЖ рдерд╛ред

рдЖрдЗрдП рдПрдХ рдЕрднрд┐рдиреЗрддрд╛ рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдЬреЛ ABActor рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдЧрд╛:

class ABActor;

class WokrerActor: public Actor {
public:
    WokrerActor(ABActor &actor)
        : abActor(actor)
    {}
public:
    void work();
private:
    void workProcess();
private:
    ABActor &abActor;
};

void WokrerActor::work() {
    addTask(std::bind(&WokrerActor::workProcess, this));
}

void WokrerActor::workProcess() {
    abActor.getA(ABActor::GetACallback(*this, [this](int a) {
        std::cout << "Result " << a << std::endl;
    }));
}

рдФрд░ рдпрд╣ рд╕рдм рдПрдХ рд╕рд╛рде рд░рдЦрд╛:

int main() {
    ABActor abActor;
    WokrerActor workerActor(abActor);

    ActorThread thread;
    thread.addActor(abActor);
    thread.addActor(workerActor);

    workerActor.work();

    thread.run();
}

рдХреЛрдб рдХреА рдкреВрд░реА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░рддреЗ рд╣реИрдВред

рд╢реБрд░реБрдЖрдд рдореЗрдВ, рд╣рдо рдЖрд╡рд╢реНрдпрдХ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдЙрдирдХреЗ рдмреАрдЪ рд╕рдВрдмрдВрдз рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВред
рддрдм рд╣рдо рдПрдХреНрдЯрд░ рд╡рд░реНрдХрд░ рдЯрд╛рд╕реНрдХ рдХрддрд╛рд░ рдореЗрдВ рд╡рд░реНрдХрдкреНрд░реЛрд╕реЗрд╕ рдХрд╛рд░реНрдп рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред
рдЬрдм рдзрд╛рдЧрд╛ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдХрддрд╛рд░ рдореЗрдВ рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдп рдХреЛ рдвреВрдВрдв рд▓реЗрдЧрд╛ рдФрд░ рдЗрд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрдЧрд╛ред
рдирд┐рд╖реНрдкрд╛рджрди рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рд╣рдо рдПрдмреАрдПрд╕рдПрдХреНрдЯрд░ рд╡рд░реНрдЧ рдХреЗ рдЧреЗрдЯрдП рд╡рд┐рдзрд┐ рдХреЛ рдХрд╣рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рдПрдмреАрдПрдХреНрдЯрд░ рд╡рд░реНрдЧ рдХреА рдХрддрд╛рд░ рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рдХрд╛рд░реНрдп рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдирд┐рд╖реНрдкрд╛рджрди рдХреЛ рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рдмрд╛рдж, рдереНрд░реЗрдб ABActor рд╡рд░реНрдЧ рд╕реЗ рдирдП рдмрдирд╛рдП рдЧрдП рдХрд╛рд░реНрдп рдХреЛ рд▓реЗ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдЗрд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдЧрд╛, рдЬрд┐рд╕рд╕реЗ рдЧреЗрдЯрдПрдкреНрд░реЛрд╕реЗрд╕ рдХреЛрдб рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рд╣реЛ рдЬрд╛рдПрдЧрд╛ред
рдпрд╣ рдХреЛрдб рдПрдХ рдХреЙрд▓рдмреИрдХ рдХрд╣реЗрдЧрд╛, рдЬрд┐рд╕рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рддрд░реНрдХ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ - рдЪрд░ рдПред рд▓реЗрдХрд┐рди рдХреЙрд▓рдмреИрдХ рдХреЗ рдмрд╛рдж рд╕реЗ рд╡рд╣ рдПрдХ рд░реИрдкрд░ рд╣реИ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рднрд░реЗ рд╣реБрдП рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХреЙрд▓рдмреИрдХ рдХреЛ рд╢реНрд░рдорд┐рдХ рд╡рд░реНрдЧ рдХреА рдХрддрд╛рд░ рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдПрдЧрд╛ред
рдФрд░ рдЬрдм, рдЪрдХреНрд░ рдХреЗ рдЕрдЧрд▓реЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдкрд░, рдереНрд░реЗрдб рдмрд╛рд╣рд░ рдЦреАрдВрдЪрддрд╛ рд╣реИ рдФрд░ рд╢реНрд░рдорд┐рдХ рд╡рд░реНрдЧ рд╕реЗ рд╣рдорд╛рд░реЗ рдХреЙрд▓рдмреИрдХ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╣рдо "10 рдкрд░рд┐рдгрд╛рдо" рд▓рд╛рдЗрди рдХрд╛ рдЖрдЙрдЯрдкреБрдЯ рджреЗрдЦреЗрдВрдЧреЗред

рдЕрднрд┐рдиреЗрддрд╛ рдврд╛рдВрдЪрд╛ рдПрдХ рджреВрд╕рд░реЗ рдХреЗ рд╕рд╛рде рд╡рд┐рднрд┐рдиреНрди рднреМрддрд┐рдХ рдзрд╛рд░рд╛рдУрдВ рдореЗрдВ рдмрд┐рдЦрд░реЗ рд╣реБрдП рд╡рд░реНрдЧреЛрдВ рдХреЗ рдкрд░рд╕реНрдкрд░ рд╕рдВрд╡рд╛рдж рдХрд╛ рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХрд╛ рд╣реИред рд╡рд░реНрдЧ рдбрд┐рдЬрд╛рдЗрди рдХреА рдЦрд╝рд╛рд╕рд┐рдпрдд, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдкрдХреЛ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдЖрд╢реНрд╡рд╕реНрдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдерд╛, рдпрд╣ рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рд╡реНрдпрдХреНрддрд┐рдЧрдд рдЕрднрд┐рдиреЗрддрд╛ рдХреЗ рднреАрддрд░ рд╕рднреА рдХреНрд░рд┐рдпрд╛рдПрдВ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдФрд░ рдПрдХ рд╣реА рдзрд╛рдЧреЗ рдореЗрдВ рдХреА рдЬрд╛рддреА рд╣реИрдВред рдзрд╛рд░рд╛рдУрдВ рдХреЗ рддреБрд▓реНрдпрдХрд╛рд▓рди рдХрд╛ рдПрдХрдорд╛рддреНрд░ рдмрд┐рдВрджреБ рдЕрднрд┐рдиреЗрддрд╛ рдврд╛рдВрдЪреЗ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рд╡рд░рдг рдореЗрдВ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЛ рджрд┐рдЦрд╛рдИ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдореНрдпреВрдЯреЗрдХреНрд╕ рдХреЛ рд▓рдкреЗрдЯрдиреЗ рдФрд░ рджреМрдбрд╝ рдХреА рд╕реНрдерд┐рддрд┐, рдЧрддрд┐рд░реЛрдз рдФрд░ рдЕрдиреНрдп рд╕рд┐рд░рджрд░реНрдж рдХреЛ рдЯреНрд░реИрдХ рдХрд░рдиреЗ рдХреА рдЪрд┐рдВрддрд╛ рдХрд┐рдП рдмрд┐рдирд╛ рдПрдХрд▓-рдереНрд░реЗрдбреЗрдб рдХреЛрдб рд▓рд┐рдЦ рд╕рдХрддрд╛ рд╣реИред

рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдХреА рдПрдХ рдХреАрдордд рд╣реИред рдЪреВрдВрдХрд┐ рдХрд┐рд╕реА рдЕрдиреНрдп рдЕрднрд┐рдиреЗрддрд╛ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдХреЗрд╡рд▓ рдХреЙрд▓рдмреИрдХ рд╕реЗ рдЙрдкрд▓рдмреНрдз рд╣реЛрддрд╛ рд╣реИ, рдЬрд▓реНрдж рдпрд╛ рдмрд╛рдж рдореЗрдВ рдЕрднрд┐рдиреЗрддрд╛ рдХреЛрдб рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИ:

    abActor.getA(ABActor::GetACallback(*this, [this](int a) {
        abActor.getB(ABActor::GetBCallback(*this, [a, this](int b) {
            abActor.saveAB(a - b, a + b, ABActor::SaveABCallback(*this, [this](){
                abActor.getA(ABActor::GetACallback(*this, [this](int a) {
                    abActor.getB(ABActor::GetBCallback(*this, [a, this](int b) {
                        std::cout << "Result " << a << " " << b << std::endl;
                    }));
                }));
            }));
        }));
    }));

рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдХреНрдпрд╛ рд╣рдо C ++ 20 - рдХреЛрд░рдЖрдЙрдЯ рдХреЗ рдирд╡рд╛рдЪрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕рд╕реЗ рдмрдЪ рд╕рдХрддреЗ рд╣реИрдВред

рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ, рд╣рдо рд╕реАрдорд╛рдУрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВрдЧреЗред

рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ, рд╣рдо рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдЕрднрд┐рдиреЗрддрд╛ рдврд╛рдВрдЪреЗ рдХреЗ рдХреЛрдб рдХреЛ рдмрджрд▓ рдирд╣реАрдВ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдЕрднрд┐рдиреЗрддрд╛ рд╡рд░реНрдЧ - ABActor рдФрд░ WorkerActor рдХреЗ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдФрд░ рдирд┐рдЬреА рддрд░реАрдХреЛрдВ рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░реЛрдВ рдХреЛ рдирд╣реАрдВ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдХреНрдпрд╛ рд╣рдо рдЗрд╕ рд╕реНрдерд┐рддрд┐ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓ рд╕рдХрддреЗ рд╣реИрдВред

Coroutinesред рднрд╛рдЧ 1. рдЖрд╡рд╛


рдХреЛрд░рдЯрд╛рдЗрди рдХрд╛ рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░ рдпрд╣ рд╣реИ рдХрд┐ рдХреЛрд░рдЯрд╛рдЗрди рдмрдирд╛рддреЗ рд╕рдордп, рдвреЗрд░ рдкрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рд╕реНрдЯреИрдХ рдлреНрд░реЗрдо рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рд╣рдо рдХрд┐рд╕реА рднреА рд╕рдордп "рдирд┐рдХрд╛рд╕" рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрдмрдХрд┐ рд╡рд░реНрддрдорд╛рди рдирд┐рд╖реНрдкрд╛рджрди рд╕реНрдерд┐рддрд┐, рдкреНрд░реЛрд╕реЗрд╕рд░ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдФрд░ рдЕрдиреНрдп рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рдмрдирд╛рдП рд░рдЦрддреЗ рд╣реИрдВред рдлрд┐рд░ рд╣рдо рдХрд┐рд╕реА рднреА рд╕рдордп рдирд┐рд▓рдВрдмрд┐рдд рдХреЛрд░реВрдЯрд╛рдЗрди рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдкрд░ рд╡рд╛рдкрд╕ рд▓реМрдЯ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдЕрдВрдд рддрдХ рдпрд╛ рдЕрдЧрд▓реЗ рдирд┐рд▓рдВрдмрди рддрдХ рдкреВрд░рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

Std :: coroutine_handle <> рдСрдмреНрдЬреЗрдХреНрдЯ рдЗрд╕ рдбреЗрдЯрд╛ рдХреЛ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ, рдЬреЛ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рд╕реНрдЯреИрдХ рдлреНрд░реЗрдо (рдФрд░ рдЕрдиреНрдп рдЖрд╡рд╢реНрдпрдХ рдбреЗрдЯрд╛) рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реВрдЪрдХ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреА рд╡рд┐рдзрд┐ (рдпрд╛ рдЗрд╕рдХреЗ рдПрдирд╛рд▓реЙрдЧ, рдСрдкрд░реЗрдЯрд░ ()) рд╣реИ, рдЬреЛ рд╣рдореЗрдВ coroutine рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП рд▓реМрдЯрд╛рддрд╛ рд╣реИред ред

рдЗрд╕ рдбреЗрдЯрд╛ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдкрд╣рд▓реЗ getAAsync рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦреЗрдВ, рдФрд░ рдлрд┐рд░ рд╕рд╛рдорд╛рдиреНрдпреАрдХрд░рдг рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред

рддреЛ, рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА std рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ :: coroutine_handle <> coro class, рд╣рдореЗрдВ рдХреНрдпрд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ?

рдЖрдкрдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рдореМрдЬреВрдж рд╡рд┐рдзрд┐ ABActor :: getA рдХреЛ рдХреЙрд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдЬреЛ рдЖрд╡рд╢реНрдпрдХрддрд╛рдиреБрд╕рд╛рд░ рд╕реНрдерд┐рддрд┐ рдХреЛ рд╣рд▓ рдХрд░реЗрдЧрд╛, рд▓реЗрдХрд┐рди рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЖрдкрдХреЛ getA рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдХреЙрд▓рдмреИрдХ рдмрдирд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдЖрдЗрдП рдпрд╛рдж рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдПрдХ рдХреЙрд▓рдмреИрдХ getA рдореЗрдердб рдХреЙрд▓рдмреИрдХ рдкрд░ рд▓реМрдЯрд╛ рд╣реИ - getA рдореЗрдердб рдХрд╛ рдкрд░рд┐рдгрд╛рдоред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрд╕ рдХреЙрд▓рдмреИрдХ рдХреЛ рдереНрд░реЗрдб рдХреЗ рд╡рд░реНрдХрд░ рдереНрд░реЗрдб рдореЗрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЗрд╕ рдХреЙрд▓рдмреИрдХ рд╕реЗ, рд╣рдо рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рдХреЛрд░рдЯрд╛рдЗрди рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рд╕рд┐рд░реНрдл рд╡рд░реНрдХрд░ рдереНрд░реЗрдб рд╕реЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдЬреЛ рдЕрдкрдиреЗ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдХреНрд░рдо рдХреЛ рдЬрд╛рд░реА рд░рдЦреЗрдЧрд╛ред рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдореЗрдВ рдХреЙрд▓рдмреИрдХ рдореЗрдВ рджрд┐рдП рдЧрдП рдкрд░рд┐рдгрд╛рдо рдХреЛ рд╕рд╣реЗрдЬрдирд╛ рд╣реЛрдЧрд╛, рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ред

auto callback = GetACallback(returnCallbackActor, [&value, coro](int result) {
        value = result;
        std::invoke(coro);
 });
getA(callback);

рддреЛ, рдЕрдм рдЖрдкрдХреЛ рдХрд╣реАрдВ рд╕реЗ coroutine_handle рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдФрд░ рдПрдХ рд▓рд┐рдВрдХ рд▓реЗрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдЖрдк рд╣рдорд╛рд░реЗ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдмрдЪрд╛ рд╕рдХрддреЗ рд╣реИрдВред

рднрд╡рд┐рд╖реНрдп рдореЗрдВ, рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк coroutine_handle рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣реИред рддрджрдиреБрд╕рд╛рд░, рд╣рдо рд╕рднреА рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЗрд╕реЗ рдХрд┐рд╕реА рдЕрдиреНрдп рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд╛рд╕ рдХрд░рдирд╛ рд╣реИред рдЖрдЗрдП рдЗрд╕ рд╕рдорд╛рд░реЛрд╣ рдХреЛ рдПрдХ рдореЗрдордиреЗ рдХреЗ рд░реВрдк рдореЗрдВ рддреИрдпрд╛рд░ рдХрд░реЗрдВред (рд╣рдо рдЙрд╕ рдЪрд░ рдХреЗ рд▓рд┐рдВрдХ рдХреЛ рдкрд╛рд╕ рдХрд░реЗрдВрдЧреЗ рдЬрд╣рд╛рдВ рдХреЙрд▓рдмреИрдХ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдХрдВрдкрдиреА рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛)ред

auto storeCoroToQueue = [&returnCallbackActor, this](auto &value, std::coroutine_handle<> coro) {
    auto callback=GetACallback(returnCallbackActor, [&value, coro](int result){
        value = result;
        std::invoke(coro);
    });
    getA(callback);
};

рд╣рдо рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЕрдЧрд▓реА рдХрдХреНрд╖рд╛ рдореЗрдВ рд╕рд╣реЗрдЬреЗрдВрдЧреЗред

struct ActorAwaiterSimple {
    int value;

    std::function<void(int &value,std::coroutine_handle<>)> forwardCoroToCallback;

    ActorAwaiterSimple(
        const std::function<void(int &value, std::coroutine_handle<>)> &forwardCoroToCallback
    )
        : forwardCoroToCallback(forwardCoroToCallback)
    {}

    ActorAwaiterSimple(const ActorAwaiterSimple &) = delete;
    ActorAwaiterSimple& operator=(const ActorAwaiterSimple &) = delete;
    ActorAwaiterSimple(ActorAwaiterSimple &&) = delete;
    ActorAwaiterSimple& operator=(ActorAwaiterSimple &&) = delete;

// ...

рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╡рд╕реНрддреБ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд, рд╣рдо рдЙрд╕ рдореВрд▓реНрдп рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА (рдЪрд░ рдорд╛рди рдХреЗ рд░реВрдк рдореЗрдВ) рднреА рдпрд╣рд╛рдВ рд░рдЦреЗрдВрдЧреЗ рдЬреЛ рд╣рдореЗрдВ рдХреЙрд▓рдмреИрдХ рдореЗрдВ рдЗрдВрддрдЬрд╛рд░ рдХрд░ рд░рд╣рд╛ рд╣реИред

рдЪреВрдБрдХрд┐ рд╣рдо рдпрд╣рд╛рдБ рдореВрд▓реНрдп рдХреЗ рддрд╣рдд рдореЗрдореЛрд░реА рд░рдЦрддреЗ рд╣реИрдВ, рд╣рдо рд╢рд╛рдпрдж рд╣реА рдЗрд╕ рд╡рд░реНрдЧ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдХреЙрдкреА рдпрд╛ рдХрд╣реАрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрд┐рд╕реА рдиреЗ рдЗрд╕ рд╡рд░реНрдЧ рдХреА рдирдХрд▓ рдХреА, рдорд╛рди рдХреЛ рд╡рд░реНрдЧ рдХреЗ рдкреБрд░рд╛рдиреЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдорд╛рди рдЪрд░ рдХреЗ рддрд╣рдд рд╕рд╣реЗрдЬрд╛, рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рдирдП рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдкрдврд╝рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ред рдФрд░ рдпрд╣ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдмрдЪрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдирдХрд▓ рд╣реБрдИред рдЕрдкреНрд░рд┐рдпред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░реЛрдВ рдХреЛ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░рдХреЗ рдФрд░ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЛ рдХреЙрдкреА рдФрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдХреЗ рдЗрд╕ рдкрд░реЗрд╢рд╛рдиреА рд╕реЗ рдЦреБрдж рдХреЛ рдмрдЪрд╛рддреЗ рд╣реИрдВред

рдЖрдЗрдП рдЗрд╕ рд╡рд░реНрдЧ рдХреЛ рд▓рд┐рдЦрдирд╛ рдЬрд╛рд░реА рд░рдЦреЗрдВред рдЕрдЧрд▓реА рд╡рд┐рдзрд┐ рдЬреЛ рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдП рд╡рд╣ рд╣реИ:

    bool await_ready() const noexcept {
        return false;
    }

рд╡рд╣ рдЗрд╕ рд╕рд╡рд╛рд▓ рдХрд╛ рдЬрд╡рд╛рдм рджреЗрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╣рдорд╛рд░рд╛ рдЕрд░реНрде рдЬрд╛рд░реА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИред рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ, рдкрд╣рд▓реА рдХреЙрд▓ рдкрд░, рд╣рдорд╛рд░рд╛ рдореВрд▓реНрдп рдЕрднреА рддрдХ рддреИрдпрд╛рд░ рдирд╣реАрдВ рд╣реИ, рдФрд░ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдХреЛрдИ рднреА рд╣рдорд╕реЗ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рдкреВрдЫреЗрдЧрд╛, рдЗрд╕рд▓рд┐рдП рдмрд╕ рдЭреВрдареЗ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдВред

рдХреЛрд░рд╛рдЙрдЯрд╛рдЗрди_рд╣реИрдВрдбрд▓ рдХрд╛ рдЙрджрд╛рд╣рд░рдг рд╣рдореЗрдВ рд╢реВрдиреНрдп рдкреНрд░рддреАрдХреНрд╖рд╛ рдкрджреНрдзрддрд┐ (std :: coroutine_handle <> coro) рдореЗрдВ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рддреЛ рдЪрд▓рд┐рдП рдЗрд╕рдореЗрдВ рд╣рдорд╛рд░реЗ рддреИрдпрд╛рд░ рдХрд┐рдП рдЧрдП рдлрд╝рдирдХрд╛рд░ рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ, рд╡рд╣рд╛рдБ рд╕реЗ рдЧреБрдЬрд░рддреЗ рд╣реБрдП рдореВрд▓реНрдп рдХреЗ рд▓рд┐рдП рдПрдХ рдореЗрдореЛрд░реА рд▓рд┐рдВрдХ рднреА рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

    void await_suspend(std::coroutine_handle<> coro) noexcept {
        std::invoke(forwardCoroToCallback, std::ref(value), coro);
    }

рдлрд╝рдВрдХреНрд╢рди рдирд┐рд╖реНрдкрд╛рджрди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╕рд╣реА рд╕рдордп рдкрд░ рдкреНрд░рддреАрдХреНрд╖рд╛-рд╡рд┐рдзрд┐ рд╡рд┐рдзрд┐ рдХрд╣рдХрд░ рдкреВрдЫрд╛ рдЬрд╛рдПрдЧрд╛ред рд╣рдо рдЕрдиреБрд░реЛрдзрдХрд░реНрддрд╛ рдХреЛ рдордирд╛ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗ:

    int await_resume() noexcept {
        return value;
    }

рдЕрдм рд╣рдорд╛рд░реЗ рддрд░реАрдХреЗ рдХреЛ co_await рдХреАрд╡рд░реНрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

const int a = co_await actor.abActor.getAAsync(actor);

рдпрд╣рд╛рдБ рдХреНрдпрд╛ рд╣реЛрдЧрд╛, рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдореЛрдЯреЗ рддреМрд░ рдкрд░ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░ рд░рд╣реЗ рд╣реИрдВред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЯрд╛рдЗрдк рдПрдХреНрдЯрд░ рдПрд╡рд╛рдЯрд░рд╕рд┐рдордкрд▓ рдХрд╛ рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬрд┐рд╕реЗ co_await рдХреЗ "рдЗрдирдкреБрдЯ" рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рд╡рд╣ рдкрд╣рд▓реЗ рдкреВрдЫреЗрдЧрд╛ (рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдХреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА) рдХреНрдпрд╛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЧрд▓рддреА рд╕реЗ рдПрдХ рд╕рдорд╛рдкреНрдд рдкрд░рд┐рдгрд╛рдо рд╣реИ (рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдирд╣реАрдВ рд╣реИ), рдлрд┐рд░ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВ рдХреЙрд▓ рдХрд░реЗрдВ, рд╕рдВрджрд░реНрдн рдореЗрдВ (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╡рд░реНрддрдорд╛рди coroutine рд╕реНрдЯреИрдХ рдлреНрд░реЗрдо рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреЗрддрдХ) рдФрд░ рдЕрдВрддрд░рд╛рдпрди рдирд┐рд╖реНрдкрд╛рджрди рдореЗрдВ рдЧреБрдЬрд░ рд░рд╣рд╛ рд╣реИред

рднрд╡рд┐рд╖реНрдп рдореЗрдВ, рдЬрдм ABActor рдЕрднрд┐рдиреЗрддрд╛ рдЕрдкрдирд╛ рдХрд╛рдо рдкреВрд░рд╛ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдкрд░рд┐рдгрд╛рдо рдХреЙрд▓рдмреИрдХ рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдкрд░рд┐рдгрд╛рдо ActorAwaiterSimple рдХреЗ рдПрдХрдорд╛рддреНрд░ (рд╢реЗрд╖ coroutine рд╕реНрдЯреИрдХ рдкрд░) рдореЗрдВ рд╕рд╣реЗрдЬрд╛ рдЬрд╛рдПрдЧрд╛ (coroutine рдХреА рдирд┐рд░рдВрддрд░рддрд╛) рдкреНрд░рд╛рд░рдВрдн рд╣реЛ рдЬрд╛рдПрдЧрд╛ред

рдХреЛрд░реБрдЯрд┐рди рдирд┐рд╖реНрдкрд╛рджрди рдЬрд╛рд░реА рд░рдЦреЗрдЧрд╛, рд╡реЗрдЯ_рд░реЗрд╕рдо рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рд╕рд╣реЗрдЬреЗ рдЧрдП рдкрд░рд┐рдгрд╛рдо рдХреЛ рд▓реЗрдЧрд╛, рдФрд░ рдЗрд╕ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдЪрд░ a рдореЗрдВ рдкрд╛рд╕ рдХрд░реЗрдЧрд╛

рдлрд┐рд▓рд╣рд╛рд▓, рд╡рд░реНрддрдорд╛рди рдСрд╡рд┐рдЯрд░ рдХреА рд╕реАрдорд╛ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдХреЗрд╡рд▓ рдХреЙрд▓рдмреИрдХ рдХреЗ рд╕рд╛рде рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЗрдВрдЯ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдЖрдЗрдП Awaiter рдХреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ:

template<typename... T>
struct ActorAwaiter {

    std::tuple<T...> values;

    std::function<void(std::tuple<T...> &values, std::coroutine_handle<>)> storeHandler;

    ActorAwaiter(const std::function<void(std::tuple<T...> &values, std::coroutine_handle<>)> &storeHandler)
        : storeHandler(storeHandler)
    {}

    ActorAwaiter(const ActorAwaiter &) = delete;
    ActorAwaiter& operator=(const ActorAwaiter &) = delete;
    ActorAwaiter(ActorAwaiter &&) = delete;
    ActorAwaiter& operator=(ActorAwaiter &&) = delete;

    bool await_ready() const noexcept {
        return false;
    }

    void await_suspend(std::coroutine_handle<> coro) noexcept {
        std::invoke(storeHandler, std::ref(values), coro);
    }

    //   bool B  ,
    //   sfinae      
    template<
        bool B=true,size_t len=sizeof...(T),std::enable_if_t<len==0 && B, int>=0
    >
    void await_resume() noexcept {

    }

    //   bool B  ,
    //   sfinae      
    template<
        bool B=true,size_t len=sizeof...(T),std::enable_if_t<len==1 && B, int>=0
    >
    auto await_resume() noexcept {
        return std::get<0>(values);
    }

    //   bool B  ,
    //   sfinae      
    template<
        bool B=true,size_t len=sizeof...(T),std::enable_if_t<len!=1 && len!=0 && B, int>=0
    >
    std::tuple<T...> await_resume() noexcept {
        return values;
    }
};

рдпрд╣рд╛рдБ рд╣рдо рдПрдХ рд╕рд╛рде рдХрдИ рдЪрд░ рдмрдЪрд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП std :: tuple рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред

Sfinae рдХреЛ рд╡реЗрдЯ_рд░реЗрд╕реБрдо рд╡рд┐рдзрд┐ рдкрд░ рд▓рдЧрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рд╕рднреА рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдЯрдкрд▓ рд╡рд╛рдкрд╕ рди рд╣реЛ рд╕рдХреЗ, рд▓реЗрдХрд┐рди рдЯрдкрд▓ рдореЗрдВ рдореМрдЬреВрдж рдорд╛рдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рд░рд┐рдЯрд░реНрди рд╢реВрдиреНрдп, рдареАрдХ 1 рддрд░реНрдХ рдпрд╛ рд╕рдВрдкреВрд░реНрдг рдЯреНрдпреВрд▓ред

рдЖрд╡рд╛рдЯрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд░реИрдкрд░ рдЦреБрдж рдЕрдм рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддреЗ рд╣реИрдВ:

template<typename MakeCallback, typename... ReturnArgs, typename Func>
static auto makeCoroCallback(const Func &func, Actor &returnCallback) {
    return [&returnCallback, func](auto &values, std::coroutine_handle<> coro) {
        auto callback = MakeCallback(returnCallback, [&values, coro](ReturnArgs&& ...result) {
            values = std::make_tuple(std::forward<ReturnArgs>(result)...);
            std::invoke(coro);
        });
        func(callback);
    };
}

template<typename MakeCallback, typename... ReturnArgs, typename Func>
static ActorAwaiter<ReturnArgs...> makeActorAwaiter(const Func &func, Actor &returnCallback) {
    const auto storeCoroToQueue = makeCoroCallback<MakeCallback, ReturnArgs...>(func, returnCallback);
    return ActorAwaiter<ReturnArgs...>(storeCoroToQueue);
}

ActorAwaiter<int> ABActor::getAAsync(Actor &returnCallback) {
    return makeActorAwaiter<GetACallback, int>(std::bind(&ABActor::getA, this, _1), returnCallback);
}

ActorAwaiter<int> ABActor::getBAsync(Actor &returnCallback) {
    return makeActorAwaiter<GetBCallback, int>(std::bind(&ABActor::getB, this, _1), returnCallback);
}

ActorAwaiter<> ABActor::saveABAsync(Actor &returnCallback, int a, int b) {
    return makeActorAwaiter<SaveABCallback>(std::bind(&ABActor::saveAB, this, a, b, _1), returnCallback);
}

рдЕрдм рдЖрдЗрдП рдЬрд╛рдиреЗрдВ рдХрд┐ рд╕реАрдзреЗ рдХреЛрд░рдЖрдЙрдЯ рдореЗрдВ рдмрдирд╛рдП рдЧрдП рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВред

Coroutinesред рднрд╛рдЧ 2. рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд░рдиреЗ рдпреЛрдЧреНрдп


C ++ рдХреА рджреГрд╖реНрдЯрд┐ рд╕реЗ, рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬрд┐рд╕рдореЗрдВ co_await, co_yield рдпрд╛ co_return рд╢рдмреНрдж рд╣реЛрддреЗ рд╣реИрдВ, рдХреЛ рдХреЛрд░рдЯрд╛рдЗрди рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдРрд╕реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкреНрд░рдХрд╛рд░ рднреА рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рд╣рдо рд╕рд╣рдордд рдереЗ рдХрд┐ рд╣рдо рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЛ рдирд╣реАрдВ рдмрджрд▓реЗрдВрдЧреЗ (рдпрд╣рд╛рдБ рдореЗрд░рд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╡рд╛рдкрд╕реА рдкреНрд░рдХрд╛рд░ рднреА рд╣рд╕реНрддрд╛рдХреНрд╖рд░ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИ), рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдХрд┐рд╕реА рддрд░рд╣ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдирд╛ рд╣реЛрдЧрд╛ред

рдЪрд▓реЛ рдПрдХ рд▓рдВрдмреЛ рдХреЛрд░рдЯрд╛рдЗрди рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рд╣рдорд╛рд░реЗ рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ:

void WokrerActor::workProcess() {
    const auto coroutine = [](WokrerActor &actor) -> ActorResumable {
        const int a = co_await actor.abActor.getAAsync(actor);
        const int b = co_await actor.abActor.getBAsync(actor);
        co_await actor.abActor.saveABAsync(actor, a - b, a + b);
        const int newA = co_await actor.abActor.getAAsync(actor);
        const int newB = co_await actor.abActor.getBAsync(actor);
        std::cout << "Result " << newA << " " << newB << std::endl;
    };

    coroutine(*this);
}

(рд▓реИрдореНрдмрджрд╛рд╕ рдХреА рдХреИрдкреНрдЪрд░-рд▓рд┐рд╕реНрдЯ рдореЗрдВ рдЗрд╕реЗ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдкрдХрдбрд╝рд╛ рдЧрдпрд╛? рддрдм рдЕрдВрджрд░ рдХрд╛ рд╕рд╛рд░рд╛ рдХреЛрдб рдереЛрдбрд╝рд╛ рдЖрд╕рд╛рди рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рд▓реЗрдХрд┐рди рдРрд╕рд╛ рд╣реБрдЖ рдХрд┐, рдЬрд╛рд╣рд┐рд░рд╛ рддреМрд░ рдкрд░, рдХрдВрдкрд╛рдЗрд▓рд░ рдореЗрдВ рд▓реИрдореНрдмреНрдбрд╛-рдХреЛрд░рдЯрд╛рдЗрди рдЕрднреА рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдХреЛрдб рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред)

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдорд╛рд░реЗ рдбрд░рд╛рд╡рдирд╛ рдХреЙрд▓рдмреИрдХ рдХреЛрдб рдЕрдм рдПрдХ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд░реИрдЦрд┐рдХ рдХреЛрдб рдореЗрдВ рдмрджрд▓ рдЧрдпрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЬреЛ рдХреБрдЫ рднреА рд╣реИ рд╡рд╣ ActorResumable class рдХрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд░рдирд╛ рд╣реИред

рдЖрдЗрдП рдЗрд╕реЗ рджреЗрдЦреЗрдВред

struct ActorResumable {
    struct promise_type {
        using coro_handle = std::coroutine_handle<promise_type>;

        auto get_return_object() { 
            //  ,    ActorResumable   promise_type
            return coro_handle::from_promise(*this);
        }

        auto initial_suspend() {
            //      
            return std::suspend_never();
        }

        auto final_suspend() {
            //      . 
            // ,     
            return std::suspend_never();
        }

        void unhandled_exception() {
            //   ,       
            std::terminate();
        }
    };

    ActorResumable(std::coroutine_handle<promise_type>) {}
};

рд╣рдорд╛рд░реЗ рд▓реИрдореНрдмреНрдбрд╛ рд╕реЗ рдЙрддреНрдкрдиреНрди рдХреЙрд░рдЯреАрди рдХрд╛ рдЫрджреНрдордХреЛрдб рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

ActorResumable coro() {
    promise_type promise;
    ActorResumable retobj = promise.get_return_object();
    auto intial_suspend = promise.initial_suspend();
    if (initial_suspend == std::suspend_always)  {
          // yield
    }
    try { 
        //  .
        const int a = co_await actor.abActor.getAAsync(actor);
        std::cout << "Result " << a << std::endl;
    } catch(...) { 
        promise.unhandled_exception();
    }
final_suspend:
    auto final_suspend = promise.final_suspend();
    if (final_suspend == std::suspend_always)  {
         // yield
    } else {
         cleanup();
    }

рдпрд╣ рд╕рд┐рд░реНрдл рдЫрджреНрдо рдХреЛрдб рд╣реИ, рдХреБрдЫ рдЪреАрдЬреЗрдВ рдЬрд╛рдирдмреВрдЭрдХрд░ рд╕рд░рд▓ рдХреА рдЬрд╛рддреА рд╣реИрдВред рдмрд╣рд░рд╣рд╛рд▓, рджреЗрдЦрддреЗ рд╣реИрдВ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИред

рдкрд╣рд▓реЗ рд╣рдо рдПрдХ рд╡рд╛рджрд╛ рдФрд░ ActorResumable рдмрдирд╛рддреЗ рд╣реИрдВред

Initial_suspend () рдХреЗ рдмрд╛рдж рд╣рдо рд╡рд┐рд░рд╛рдо рдирд╣реАрдВ рджреЗрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред рд╣рдо рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдореБрдЦреНрдп рднрд╛рдЧ рдХреЛ рдЕрдВрдЬрд╛рдо рджреЗрдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред

рдЬрдм рд╣рдореЗрдВ co_await рдорд┐рд▓рддрд╛ рд╣реИ, рддреЛ рд╣рдо рд╕рдордЭрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдореЗрдВ рд░реЛрдХрдирд╛ рд╣реЛрдЧрд╛ред рд╣рдордиреЗ рдкрд┐рдЫрд▓реЗ рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдХреА рдкрд╣рд▓реЗ рд╣реА рдЬрд╛рдВрдЪ рдХрд░ рд▓реА рд╣реИ, рдЖрдк рдЗрд╕ рдкрд░ рд╡рд╛рдкрд╕ рд▓реМрдЯ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЬрдм рд╣рдордиреЗ рдирд┐рд╖реНрдкрд╛рджрди рдЬрд╛рд░реА рд░рдЦрд╛ рдФрд░ рд╕реНрдХреНрд░реАрди рдкрд░ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛, рддреЛ рдХреЛрд░рдЯрд╛рдЗрди рдирд┐рд╖реНрдкрд╛рджрди рд╕рдорд╛рдкреНрдд рд╣реЛ рдЧрдпрд╛ред рд╣рдо рдЕрдВрддрд┐рдо_рд╕реНрдкреЗрдВрдб рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рдкреВрд░реЗ рд╕рдВрджрд░реНрдн рдХреЛ рд╕рд╛рдлрд╝ рдХрд░рддреЗ рд╣реИрдВред

Coroutinesред рднрд╛рдЧ 3. рдХрд╛рд░реНрдп


рдЖрдЗрдП рдпрд╛рдж рдХрд░реЗрдВ рдХрд┐ рдЕрдм рд╣рдо рдХрд┐рд╕ рдореБрдХрд╛рдо рдкрд░ рдкрд╣реБрдВрдЪреЗ рд╣реИрдВред

void WokrerActor::workProcess() {
    const auto coroutine = [](WokrerActor &actor) -> ActorResumable {
        const int a = co_await actor.abActor.getAAsync(actor);
        const int b = co_await actor.abActor.getBAsync(actor);
        co_await actor.abActor.saveABAsync(actor, a - b, a + b);
        const int newA = co_await actor.abActor.getAAsync(actor);
        const int newB = co_await actor.abActor.getBAsync(actor);
        std::cout << "Result " << newA << " " << newB << std::endl;
    };

    coroutine(*this);
}

рдпрд╣ рдЕрдЪреНрдЫрд╛ рд▓рдЧ рд░рд╣рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рджреЗрдЦрдирд╛ рдЖрд╕рд╛рди рд╣реИ рдХрд┐ рдХреЛрдб:

        const int a = co_await actor.abActor.getAAsync(actor);
        const int b = co_await actor.abActor.getBAsync(actor);

2 рдмрд╛рд░ рджреЛрд╣рд░рд╛рдпрд╛ред рдХреНрдпрд╛ рдЗрд╕ рдкрд▓ рдХреЛ рдлрд┐рд░ рд╕реЗ рднрд░рдирд╛ рдФрд░ рдПрдХ рдЕрд▓рдЧ рдХрд╛рд░реНрдп рдореЗрдВ рдбрд╛рд▓рдирд╛ рд╕рдВрднрд╡ рд╣реИ?

рдЖрдЗрдП рдЬрд╛рдиреЗрдВ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:

CoroTask<std::pair<int, int>> WokrerActor::readAB() {
    const int a = co_await abActor.getAAsync2(*this);
    const int b = co_await abActor.getBAsync2(*this);
    co_return std::make_pair(a, b);
}

void WokrerActor::workCoroProcess() {
    const auto coroutine = [](WokrerActor &actor) -> ActorResumable {
        const auto [a, b] = co_await actor.readAB();
        co_await actor.abActor.saveABAsync2(actor, a - b, a + b);
        const auto [newA, newB] = co_await actor.readAB();
        std::cout << "Result " << newA << " " << newB << " " << a << " " << b << std::endl;
    };

    coroutine(*this);
}

рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЬреЛ рдХреБрдЫ рднреА рд╣реИ рд╡рд╣ рдХреЙрд░рдЯрд╕реНрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд░рдирд╛ рд╣реИред рдЗрд╕реЗ рдЦрддреНрдо рдХрд░рдиреЗ рдХреА рд╕реЛрдЪрддреЗ рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, read_ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЕрдВрджрд░ co_return рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ CoroTask рдХреЛ рдкреБрдирд░рд╛рд░рдВрдн рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдкреВрд░рд╛ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рд╕рд╛рде рд╣реА, рдЗрд╕ рд╡рд░реНрдЧ рдХреА рдПрдХ рд╡рд╕реНрддреБ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рд╕реА рдЕрдиреНрдп рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рд╕рд╣_рд╡рд╛рдЗрдЯ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдХреЛрд░реЛрд╕реНрдХ рдХреНрд▓рд╛рд╕ рдХреЛ рдПрдПрдПрдлрд╝рд┐рдЯреЗрдмрд▓ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рднреА рд╕рдВрддреБрд╖реНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЖрдЗрдП рдХреЛрд░реЛрд╕реНрдХ рдХреНрд▓рд╛рд╕ рдореЗрдВ рдЗрди рджреЛрдиреЛрдВ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░реЗрдВ:

template <typename T = void>
struct CoroTask {
    struct promise_type {
        T result;
        std::coroutine_handle<> waiter;

        auto get_return_object() {
            return CoroTask{*this};
        }

        void return_value(T value) {
            result = value;
        }

        void unhandled_exception() {
            std::terminate();
        }

        std::suspend_always initial_suspend() {
            return {};
        }

        auto final_suspend() {
            struct final_awaiter {
                bool await_ready() {
                    return false;
                }
                void await_resume() {}
                auto await_suspend(std::coroutine_handle<promise_type> me) {
                    return me.promise().waiter;
                }
            };
            return final_awaiter{};
        }
    };

    CoroTask(CoroTask &&) = delete;
    CoroTask& operator=(CoroTask&&) = delete;
    CoroTask(const CoroTask&) = delete;
    CoroTask& operator=(const CoroTask&) = delete;

    ~CoroTask() {
        if (h) {
            h.destroy();
        }
    }

    explicit CoroTask(promise_type & p)
        : h(std::coroutine_handle<promise_type>::from_promise(p))
    {}

    bool await_ready() {
        return false;
    }

    T await_resume() {
        auto &result = h.promise().result;
        return result;
    }

    void await_suspend(std::coroutine_handle<> waiter) {
        h.promise().waiter = waiter;
        h.resume();
    }
private:
    std::coroutine_handle<promise_type> h;
};

(рдореИрдВ рджреГрдврд╝рддрд╛ рд╕реЗ рдЗрд╕ рдкреЛрд╕реНрдЯ рдХреА рдкреГрд╖реНрдарднреВрдорд┐ рдЫрд╡рд┐ рдХреЛ рдЦреЛрд▓рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред рднрд╡рд┐рд╖реНрдп рдореЗрдВ, рдпрд╣ рдЖрдкрдХреА рдмрд╣реБрдд рдорджрдж рдХрд░реЗрдЧрд╛ред)

рддреЛ, рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рдпрд╣рд╛рдВ рдХреНрдпрд╛ рд╣реЛрддрд╛ рд╣реИред

1. рд▓реИрдореНрдмреНрдбрд╛ рдХреЛрд░рдЯрд╛рдЗрди рдкрд░ рдЬрд╛рдПрдВ рдФрд░ рддреБрд░рдВрдд рд╡реЛрдХрд░рд░реНрд░рд┐рдПрдХ :: рд░реАрдбрдм рдХреЛрд░рдЖрдЙрдЯ рдХрд░реЗрдВред рд▓реЗрдХрд┐рди рдЗрд╕ рдХреЛрд░рдЖрдЙрдЯ рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдЗрд╕реЗ рдЖрд░рдВрдн рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ (initial_suspend == Suspend_always), рдЬреЛ рд╣рдореЗрдВ рдмрд╛рдзрд┐рдд рдХрд░рдиреЗ рдФрд░ рдХреЛрд░рдЯрд╛рдЗрди рд▓реИрдореНрдмреНрдбрд╛ рдореЗрдВ рд▓реМрдЯрдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рддрд╛ рд╣реИред

2. co_await lambda рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рдБрдЪ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд░реАрдбрдм рддреИрдпрд╛рд░ рд╣реИред рдкрд░рд┐рдгрд╛рдо рддреИрдпрд╛рд░ рдирд╣реАрдВ рд╣реИ (рдЗрдВрддрдЬрд╛рд░ рдХрд░ рд░рд╣рд╛ рд╣реИ == рдЭреВрдард╛), рдЬреЛ рдЗрд╕реЗ рдХреЛрд░реЛрд╕реНрдХреИрд╕ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рд╕рдВрджрд░реНрдн рдХреЛ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рддрд╛ рд╣реИ :: рдкреНрд░рддреАрдХреНрд╖рд╛ рд╡рд┐рдзрд┐ред рдЗрд╕ рд╕рдВрджрд░реНрдн рдХреЛ рдХреЛрд░рдЯрд╕реНрдХ рдореЗрдВ рд╕рд╣реЗрдЬрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рд░реАрдбрдм

3 рдХреЙрд░рдЯрд╛рдЗрдиреНрд╕ рдХрд╛ рдлрд┐рд░ рд╕реЗ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ред рд░реАрдбрдм рдХреЙрд░рдЖрдЙрдЯ рдХреЗ рдмрд╛рдж рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкреВрд░рд╛ рдХрд░ рд▓рд┐рдпрд╛ рд╣реИ, рдпрд╣ рд▓рд╛рдЗрди рддрдХ рдкрд╣реБрдБрдЪрддрд╛ рд╣реИ:

co_return std::make_pair(a, b);

рдирддреАрдЬрддрди, CoroTask :: рд╡рд╛рджрд╛_type :: return_value рд╡рд┐рдзрд┐ рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ CoroTask рдХреЗ рдЕрдВрджрд░ :: рд╡рд╛рджрд╛_type рд╡рд┐рдзрд┐ рд╕рдВрдЦреНрдпрд╛

4 рдХреА рдмрдирд╛рдИ рдЧрдИ рдЬреЛрдбрд╝реА рдХреЛ рдмрдЪрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ ред рдЪреВрдВрдХрд┐ co_return рд╡рд┐рдзрд┐ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП coroutine рдХрд╛ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ CoroTask :: рд╡рд╛рджрд╛_type :: рдЕрдВрддрд┐рдо рд░реВрдк рд╕реЗред ред рдпрд╣ рд╡рд┐рдзрд┐ рдПрдХ рд╕реНрд╡-рд▓рд┐рдЦрд┐рдд рд╕рдВрд░рдЪрдирд╛ рд▓реМрдЯрд╛рддреА рд╣реИ (рдЪрд┐рддреНрд░ рдХреЛ рджреЗрдЦрдирд╛ рди рднреВрд▓реЗрдВ), рдЬреЛ рдЖрдкрдХреЛ рдЕрдВрддрд┐рдо_рд╡рд╛рдЯрд░ :: рд╡реЗрдЯ_рд╕рдкреЗрдВрдбреЗрдВрдЯ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рддреА рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдЪрд░рдг 2 рдореЗрдВ рд╕рд╣реЗрдЬреЗ рдЧрдП рдХреЛрд░рдЯрд╛рдЗрди рд▓реИрдореНрдмреНрдбрд╛ рд╕рдВрджрд░реНрдн рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рд╣рдо рдпрд╣рд╛рдВ рд╕реЗ рдХреЗрд╡рд▓ suspend_always рдХреНрдпреЛрдВ рдирд╣реАрдВ рд▓реМрдЯрд╛ рд╕рдХрддреЗ? рдЖрдЦрд┐рд░рдХрд╛рд░, рдЗрд╕ рд╡рд░реНрдЧ рдХреЗ рд╢реБрд░реБрдЖрддреА_рд╕реБрдзрд╛рд░ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдХреНрдпрд╛ рд╣рдо рд╕рдлрд▓ рд╣реБрдП? рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдЖрд░рдВрднрд┐рдХ_рд╕реБрдзрд╛рд░ рдореЗрдВ рд╣рдо рд╕рдлрд▓ рд╣реБрдП рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕ рдХреЙрд░рдЯреАрди рдХреЛ рд╣рдорд╛рд░реЗ рд▓реИрдореНрдмреНрдбрд╛ рдХреЙрд░рдЯреАрди рджреНрд╡рд╛рд░рд╛ рдмреБрд▓рд╛рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рд╣рдо рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдЖ рдЧрдПред рд▓реЗрдХрд┐рди рдЙрд╕ рд╕рдордп рдЬрдм рд╣рдо рдЕрдВрддрд┐рдо_рд╕рдкреЗрдВрдб рдХреЙрд▓ рдкрд░ рдкрд╣реБрдБрдЪреЗ, рд╣рдорд╛рд░реА рдХреЛрд░рдЖрдЙрдЯ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рдПрдХ рдФрд░ рд╕реНрдЯреИрдХ (рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рд▓реИрдореНрдмрдбрд╛ рдХрд┐ рдореЗрдХ рдХреЙрд░реЙрдХрдмреИрдХ рдлрд╝рдВрдХреНрд╢рди рддреИрдпрд╛рд░) рд╕реЗ рдЬрд╛рд░реА рд░рд╣реА, рдФрд░ рдЕрдЧрд░ рд╣рдо рд╕рд╕реНрдкреЗрдВрдб_рд▓рд╡реЗрдЬрд╝ рдпрд╣рд╛рдБ рд▓реМрдЯреЗ, рддреЛ рд╣рдо рдЗрд╕реЗ рд╡рд╛рдкрд╕ рдХрд░ рджреЗрдВрдЧреЗ, рдФрд░ рд╡рд░реНрдХрдЪреЛрд░реЛрдкреНрд░реЛрд╕реЗрд╕ рд╡рд┐рдзрд┐ рд╕реЗ рдирд╣реАрдВред

5. рдЪреВрдВрдХрд┐ рдЕрдВрддрд┐рдо_рд╡рд╛рдЯрд░ :: рдкреНрд░рддреАрдХреНрд╖рд┐рдд_рд╕реБрдзрд╛рд░ рд╡рд┐рдзрд┐ рдиреЗ рд╕рдВрджрд░реНрдн рдХреЛ рд╣рдореЗрдВ рд▓реМрдЯрд╛ рджрд┐рдпрд╛, рдпрд╣ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рджрд┐рдП рдЧрдП рд╕рдВрджрд░реНрдн рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╛рд░реА рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╛рдзреНрдп рдХрд░рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рддреН, рдХреЛрд░рдЯрд╛рдЗрди рд▓реИрдореНрдмреНрдбрд╛ред рдЪреВрдВрдХрд┐ рдирд┐рд╖реНрдкрд╛рджрди рдмрд┐рдВрджреБ рдкрд░ рд▓реМрдЯ рдЖрдпрд╛:

const auto [a, b] = co_await actor.readAB();

рдлрд┐рд░ рд╣рдореЗрдВ CoroTask :: wait_resume рдкрджреНрдзрддрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рд╕рд╣реЗрдЬреЗ рдЧрдП рдкрд░рд┐рдгрд╛рдо рдХреЛ рдЕрд▓рдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ, рдЪрд░ рдП рдФрд░ рдмреА рдХреЛ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЕрдм рдХреЛрд░рдЯрд╕реНрдХ рдЙрджрд╛рд╣рд░рдг рдирд╖реНрдЯ рд╣реЛ рдЧрдпрд╛ рд╣реИред

6. рдХреЛрд░реЛрд╕реНрдХреИрд╕ рдХрд╛ рдЙрджрд╛рд╣рд░рдг рдирд╖реНрдЯ рд╣реЛ рдЧрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рд╡реЛрдХрд░рд░реИрдХреНрдЯрд░ :: readAB рд╕рдВрджрд░реНрдн рдХрд╛ рдХреНрдпрд╛ рд╣реБрдЖ? рдпрджрд┐ рд╣рдо CoroTask рд╕реЗ :: рд╡рд╛рджрд╛_рдЯрд╛рдЗрдк :: рдлрд╛рдЗрдирд▓_рд╕реНрдкреЗрдиреНрдб рд╕рд╕реНрдкреЗрдВрдб_рдирдПрд╡рд░ (рдФрд░ рдЕрдзрд┐рдХ рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ, рдЙрд╕ рдкрд░ рд▓реМрдЯреЗрдЧрд╛, рдЬреЛ рдкреНрд░рддреАрдХреНрд╖рд╛ рдореЗрдВ рд╣реИ рдХрд┐ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреНрд░рд╢реНрди рд╕рд╣реА рд╣реЛ рдЬрд╛рдПрдЧрд╛), рддреЛ рдЙрд╕ рд╕рдордп рдХреЛрд░рдЯрд╛рдЗрди рд╕рдВрджрд░реНрдн рд╕рд╛рдл рд╣реЛ рдЬрд╛рдПрдЧрд╛ред рд▓реЗрдХрд┐рди рдЬрдм рд╕реЗ рд╣рдордиреЗ рдирд╣реАрдВ рдХрд┐рдпрд╛, рд╕рдВрджрд░реНрдн рдХреЛ рд╕рд╛рдл рдХрд░рдиреЗ рдХрд╛ рджрд╛рдпрд┐рддреНрд╡ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╣рдо рдЗрд╕ рд╕рдВрджрд░реНрдн рдХреЛ рдХреЛрд░рдЯрд╕реНрдХ рд╡рд┐рдзреНрд╡рдВрд╕рдХ рдореЗрдВ рд╕рд╛рдл рдХрд░ рджреЗрдВрдЧреЗ, рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕реБрд░рдХреНрд╖рд┐рдд рд╣реИред

7. рдХреЛрд░рдЯрд╛рдЗрди рд░реАрдбрдм рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ, рд╕рдВрджрд░реНрдн рд╕рд╛рдл рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реИрдореНрдмреНрдбрд╛ рдХреЛрд░рдЯрд╛рдЗрди рдЪрд▓рддрд╛ рд░рд╣рддрд╛ рд╣реИ ...

рдЬреИрд╕реЗ-рддреИрд╕реЗ рдЫрд╛рдБрдЯреЗред рдХреНрдпрд╛ рдЖрдкрдХреЛ рдпрд╛рдж рд╣реИ рдХрд┐ ABActor :: getAAsync () рдФрд░ рдЗрд╕реА рддрд░рд╣ рдХреЗ рддрд░реАрдХреЛрдВ рд╕реЗ, рд╣рдо рдПрдХ рд╕реНрд╡-рд▓рд┐рдЦрд┐рдд рд╕рдВрд░рдЪрдирд╛ рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ? рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, GetAAsync рд╡рд┐рдзрд┐ рдХреЛ CoroTask рдФрд░ ActorAwaiter рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдЬреНрдЮрд╛рди рдХреЗ рд╕рдВрдпреЛрдЬрди рдХреЗ рд╕рд╛рде рдПрдХ рдХреЙрд░рдЖрдЙрдЯ рдореЗрдВ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдХреБрдЫ рдРрд╕рд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

CoroTaskActor<int> ABActor::getAAsync(Actor &returnCallback) {
    co_return makeCoroCallback<GetACallback, int>(std::bind(&ABActor::getA, this, _1), returnCallback);
}

рд▓реЗрдХрд┐рди рдпрд╣ рдореИрдВ рдЖрддреНрдо-рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рд▓рд┐рдП рдЫреЛрдбрд╝ рджреВрдВрдЧрд╛ред

рдЬрд╛рдБрдЪ - рдкрд░рд┐рдгрд╛рдо


рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдХреЛрд░рдЯрд╛рдЗрди рдХреА рдорджрдж рд╕реЗ, рдЖрдк рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдХреЙрд▓рдмреИрдХ рдХреЛрдб рдХреЛ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд░реИрдЦрд┐рдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╕рдЪ рд╣реИ, рд╕рд╣рд╛рдпрдХ рдкреНрд░рдХрд╛рд░ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЕрднреА рддрдХ рдмрд╣реБрдд рд╕рд╣рдЬ рдирд╣реАрдВ рд▓рдЧрддреА рд╣реИред

рд╕рднреА рдХреЛрдб рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реИред рдореИрдВ

рдпрд╣ рднреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рд╡рд┐рд╖рдп рдХреЗ рдЕрдзрд┐рдХ рд╕рдВрдкреВрд░реНрдг рд╡рд┐рд╕рд░реНрдЬрди рдХреЗ рд▓рд┐рдП рдЗрди рд╡реНрдпрд╛рдЦреНрдпрд╛рдиреЛрдВ рдХреЛ рджреЗрдЦреЗрдВ
ред
рдПрдХ рд╣реА рд▓реЗрдЦрдХ рд╕реЗ рдХреЛрд░рдЯрд╛рдЗрди рдХреЗ рд╡рд┐рд╖рдп рдкрд░ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдЙрджрд╛рд╣рд░рдг рдпрд╣рд╛рдВ рджрд┐рдП рдЧрдП рд╣реИрдВ ред
рдФрд░ рдЖрдк рдЗрд╕ рд╡реНрдпрд╛рдЦреНрдпрд╛рди рдХреЛ рднреА рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ ред

All Articles