您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > C/C++/C#

从0到1用c++实现一个Actor模型

时间:2023-07-22 14:20:08  来源:今日头条  作者:Red果果

C++中的Actor模型是一种并发编程模型,它通过将计算单元封装为独立、可并发执行的Actor实例,来实现并发和消息传递。每个Actor都有自己的状态和行为,并且通过接收和发送消息来进行通信。Actor之间是完全隔离的,它们之间只能通过消息进行通信,从而避免了共享状态和显式锁的问题。

下面是一个简单的C++ Actor模型的示例实现:

#include <IOStream>
#include <queue>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>

class Actor {
public:
    void run() {
        while (!stop) {
            std::function<void()> message;

            {
                std::unique_lock<std::mutex> lock(mutex);

                condition.wAIt(lock, [this]() {
                    return stop || !messageQueue.empty();
                });

                if (stop && messageQueue.empty()) {
                    return;
                }

                message = std::move(messageQueue.front());
                messageQueue.pop();
            }

            message();
        }
    }

    template<typename F, typename... Args>
    void send(F&& f, Args&&... args) {
        {
            std::lock_guard<std::mutex> lock(mutex);
            messageQueue.emplace(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
        }

        condition.notify_one();
    }

    void stopActor() {
        {
            std::lock_guard<std::mutex> lock(mutex);
            stop = true;
        }

        condition.notify_all();
    }

private:
    std::queue<std::function<void()>> messageQueue;
    std::mutex mutex;
    std::condition_variable condition;
    bool stop = false;
};

// 示例Actor行为
class MyActor {
public:
    void doSomething(int id) {
        std::cout << "Actor ID: " << id << ", thread ID: " << std::this_thread::get_id() << std::endl;
        // 具体行为逻辑
    }
};

int main() {
    MyActor actor;

    Actor actingThread;

    actingThread.send([&actor]() {
        actor.doSomething(1);
    });

    actingThread.send([&actor]() {
        actor.doSomething(2);
    });

    actingThread.send([&actingThread]() {
        actingThread.stopActor();
    });

    std::thread thread([&actingThread]() {
        actingThread.run();
    });

    thread.join();

    return 0;
}

上述代码实现了一个简单的Actor模型。在Actor类中,使用条件变量和互斥锁来实现Actor的同步和通信。每个Actor都维护一个消息队列,通过send方法向队列中添加消息。

在main函数中,示例代码创建了一个MyActor对象并实例化了一个Actor对象。通过调用Actor对象的send方法,将消息发送给MyActor对象。MyActor对象中的doSomething方法会在调用线程的上下文中执行。

然后,通过调用stopActor方法停止Actor线程。最后,创建一个新线程运行Actor的run方法来处理消息队列中的消息。

请注意,上述示例代码只是一个简单的Actor模型的实现,实际使用时可能需要考虑更多的细节,如Actor之间的连接、创建多个Actor对象、消息路由等。Actor模型可以作为实现并发和并行的一种有趣和强大的方式,它可以提供更好的抽象和隔离性来处理并发编程中的问题。

添加actor之间的连接功能

要实现Actor之间的连接功能,可以使用一个中央调度器来管理Actor之间的消息传递和通信。下面是一个示例的C++ Actor模型的实现,包括Actor之间的连接功能:

#include <iostream>
#include <queue>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>
#include <unordered_map>

class Actor {
public:
    void run() {
        while (!stop) {
            std::function<void()> message;

            {
                std::unique_lock<std::mutex> lock(mutex);

                condition.wait(lock, [this]() {
                    return stop || !messageQueue.empty();
                });

                if (stop && messageQueue.empty()) {
                    return;
                }

                message = std::move(messageQueue.front());
                messageQueue.pop();
            }

            message();
        }
    }

    template<typename F, typename... Args>
    void send(F&& f, Args&&... args) {
        {
            std::lock_guard<std::mutex> lock(mutex);
            messageQueue.emplace(std::bind(std::forward<F>(f), std::forward<Args>(args)...));
        }

        condition.notify_one();
    }

    void stopActor() {
        {
            std::lock_guard<std::mutex> lock(mutex);
            stop = true;
        }

        condition.notify_all();
    }

private:
    std::queue<std::function<void()>> messageQueue;
    std::mutex mutex;
    std::condition_variable condition;
    bool stop = false;
};

class ActorSystem {
public:
    ActorSystem() {
        std::thread thread([this]() {
            this->run();
        });
        thread.detach();
    }

    template<typename T>
    Actor& createActor() {
        std::unique_lock<std::mutex> lock(mutex);

        Actor* actor = new Actor();
        actors.emplace(actorId, actor);
        actorId++;

        return *actor;
    }

    void sendMessage(int actorId, std::function<void()> message) {
        std::unique_lock<std::mutex> lock(mutex);

        if (actors.find(actorId) != actors.end()) {
            actors[actorId]->send(message);
        }
    }

    void stopActor(int actorId) {
        std::unique_lock<std::mutex> lock(mutex);

        if (actors.find(actorId) != actors.end()) {
            actors[actorId]->stopActor();
            delete actors[actorId];
            actors.erase(actorId);
        }
    }

private:
    void run() {
        while (true) {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));

            std::unique_lock<std::mutex> lock(mutex);

            for (const auto& actor : actors) {
                actor.second->run();
            }
        }
    }

    std::unordered_map<int, Actor*> actors;
    int actorId = 0;
    std::mutex mutex;
};

// 示例Actor行为
class MyActor {
public:
    MyActor(ActorSystem& actorSystem) : actorSystem(actorSystem) {}

    void doSomething(int id) {
        std::cout << "Actor ID: " << id << ", thread ID: " << std::this_thread::get_id() << std::endl;
        // 具体行为逻辑

        // 发送消息给其他Actor
        actorSystem.sendMessage(1, [this]() {
            this->doSomethingElse();
        });
    }

    void doSomethingElse() {
        std::cout << "Doing something else" << std::endl;
        // 具体行为逻辑
    }

private:
    ActorSystem& actorSystem;
};

int main() {
    ActorSystem actorSystem;

    MyActor actor1(actorSystem);
    MyActor actor2(actorSystem);

    Actor& actor1Ref = actorSystem.createActor<MyActor>();
    Actor& actor2Ref = actorSystem.createActor<MyActor>();

    actor1Ref.send([&actor1]() {
        actor1.doSomething(1);
    });

    actor2Ref.send([&actor2]() {
        actor2.doSomething(2);
    });

    std::this_thread::sleep_for(std::chrono::seconds(5));

    actorSystem.stopActor(0);
    actorSystem.stopActor(1);

    return 0;
}

上述代码中,我们引入了一个ActorSystem类来管理所有的Actor。ActorSystem类中维护了一个unordered_map来存储Actor的ID和指针的映射关系。createActor方法用于创建新的Actor,并返回其引用。sendMessage方法用于向指定的Actor发送消息,stopActor方法用于停止指定的Actor。

在MyActor类中,我们添加了一个doSomethingElse方法,用于演示如何向其他Actor发送消息。在doSomething方法中,我们通过actorSystem.sendMessage方法向ID为1的Actor发送消息。

在main函数中,我们创建了两个MyActor对象,并通过createActor方法创建了两个对应的Actor。然后,我们通过调用send方法向两个Actor发送消息。最后,我们通过调用stopActor方法停止两个Actor。

请注意,上述示例代码只是一个简单的Actor模型的实现,实际使用时可能需要考虑更多的细节,如消息路由、Actor之间的连接关系、消息队列的优化等。Actor模型是一种强大的并发编程模型,可以提供更好的抽象和隔离性来处理并发编程中的问题。

再添加消息路由功能

要添加消息路由功能,我们可以为ActorSystem类添加一个Router类成员变量,并在sendMessage方法中使用路由器来选择目标Actor。下面是更新后的代码:

class Router {
public:
    virtual int route(const std::unordered_map<int, Actor*>& actors) = 0;
};

class RoundRobinRouter : public Router {
public:
    int route(const std::unordered_map<int, Actor*>& actors) override {
        if (actors.empty()) {
            return -1;
        }

        currentActorIndex = (currentActorIndex + 1) % actors.size();
        auto it = std::next(actors.begin(), currentActorIndex);
        return it->first;
    }

private:
    int currentActorIndex = -1;
};

class ActorSystem {
public:
    ActorSystem() {
        std::thread thread([this]() {
            this->run();
        });
        thread.detach();
    }

    template<typename T>
    Actor& createActor() {
        std::unique_lock<std::mutex> lock(mutex);

        Actor* actor = new Actor();
        actors.emplace(actorId, actor);
        actorId++;

        return *actor;
    }

    void sendMessage(std::function<void()> message, Router* router = nullptr) {
        std::unique_lock<std::mutex> lock(mutex);

        int actorId = -1;

        if (router != nullptr) {
            actorId = router->route(actors);
        } else {
            if (!actors.empty()) {
                actorId = actors.begin()->first;
            }
        }

        if (actorId != -1) {
            actors[actorId]->send(message);
        }
    }

    void stopActor(int actorId) {
        std::unique_lock<std::mutex> lock(mutex);

        if (actors.find(actorId) != actors.end()) {
            actors[actorId]->stopActor();
            delete actors[actorId];
            actors.erase(actorId);
        }
    }

private:
    void run() {
        while (true) {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));

            std::unique_lock<std::mutex> lock(mutex);

            for (const auto& actor : actors) {
                actor.second->run();
            }
        }
    }

    std::unordered_map<int, Actor*> actors;
    int actorId = 0;
    std::mutex mutex;
};

在上述代码中,我们添加了一个Router类和一个具体的RoundRobinRouter类。Router类是一个抽象类,其中定义了一个route方法,用于根据一组Actor选择目标Actor。RoundRobinRouter类是一个具体的路由器实现,它使用轮询的方式选择目标Actor。

在ActorSystem类中,我们添加了一个可选的路由器参数router,并在sendMessage方法中使用路由器来选择目标Actor。如果没有指定路由器,则默认选择第一个Actor。

你可以根据需要实现其他的路由器策略,比如随机选择、基于消息负载的选择等。

使用示例代码:

int main() {
    ActorSystem actorSystem;

    MyActor actor1(actorSystem);
    MyActor actor2(actorSystem);

    Actor& actor1Ref = actorSystem.createActor<MyActor>();
    Actor& actor2Ref = actorSystem.createActor<MyActor>();

    RoundRobinRouter router;

    actorSystem.sendMessage([&actor1]() {
        actor1.doSomething(1);
    }, &router);

    actorSystem.sendMessage([&actor2]() {
        actor2.doSomething(2);
    }, &router);

    std::this_thread::sleep_for(std::chrono::seconds(5));

    actorSystem.stopActor(0);
    actorSystem.stopActor(1);

    return 0;
}

在上述示例代码中,我们创建了一个RoundRobinRouter对象,并将其作为参数传递给sendMessage方法。这样,消息将根据轮询策略路由到不同的Actor上。

请注意,上述示例代码仅仅是一个简单的消息路由实现,实际使用时可能需要考虑更多的细节,比如路由策略的灵活性、动态添加/删除Actor时的路由更新等。

进一步优化路由策略的灵活性

要优化路由策略的灵活性,我们可以将路由策略从Router类中分离出来,并使用策略模式来实现。下面是更新后的代码:

class RoutingStrategy {
public:
    virtual int selectActor(const std::unordered_map<int, Actor*>& actors) = 0;
};

class Router {
public:
    Router(RoutingStrategy* strategy) : strategy(strategy) {}

    int route(const std::unordered_map<int, Actor*>& actors) {
        return strategy->selectActor(actors);
    }

private:
    RoutingStrategy* strategy;
};

class RoundRobinStrategy : public RoutingStrategy {
public:
    int selectActor(const std::unordered_map<int, Actor*>& actors) override {
        if (actors.empty()) {
            return -1;
        }

        currentActorIndex = (currentActorIndex + 1) % actors.size();
        auto it = std::next(actors.begin(), currentActorIndex);
        return it->first;
    }

private:
    int currentActorIndex = -1;
};

class RandomStrategy : public RoutingStrategy {
public:
    int selectActor(const std::unordered_map<int, Actor*>& actors) override {
        if (actors.empty()) {
            return -1;
        }

        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_int_distribution<> dis(0, actors.size() - 1);

        auto it = std::next(actors.begin(), dis(gen));
        return it->first;
    }
};

class ActorSystem {
public:
    ActorSystem() {
        std::thread thread([this]() {
            this->run();
        });
        thread.detach();
    }

    template<typename T>
    Actor& createActor() {
        std::unique_lock<std::mutex> lock(mutex);

        Actor* actor = new Actor();
        actors.emplace(actorId, actor);
        actorId++;

        return *actor;
    }

    void sendMessage(std::function<void()> message, RoutingStrategy* strategy = nullptr) {
        std::unique_lock<std::mutex> lock(mutex);

        int actorId = -1;

        if (strategy != nullptr) {
            actorId = strategy->selectActor(actors);
        } else {
            if (!actors.empty()) {
                actorId = actors.begin()->first;
            }
        }

        if (actorId != -1) {
            actors[actorId]->send(message);
        }
    }

    void stopActor(int actorId) {
        std::unique_lock<std::mutex> lock(mutex);

        if (actors.find(actorId) != actors.end()) {
            actors[actorId]->stopActor();
            delete actors[actorId];
            actors.erase(actorId);
        }
    }

private:
    void run() {
        while (true) {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));

            std::unique_lock<std::mutex> lock(mutex);

            for (const auto& actor : actors) {
                actor.second->run();
            }
        }
    }

    std::unordered_map<int, Actor*> actors;
    int actorId = 0;
    std::mutex mutex;
};

在上述代码中,我们将路由策略从Router类中分离出来,并定义了一个RoutingStrategy抽象类。RoutingStrategy类中定义了一个selectActor方法,用于根据一组Actor选择目标Actor。

然后,我们实现了两个具体的路由策略类:RoundRobinStrategy和RandomStrategy。RoundRobinStrategy类使用轮询的方式选择目标Actor,RandomStrategy类使用随机选择的方式选择目标Actor。

在Router类中,我们使用了策略模式,将具体的路由策略对象存储在成员变量中,并在route方法中调用策略对象的selectActor方法。

在ActorSystem类中,我们添加了一个可选的策略参数strategy,并在sendMessage方法中使用策略对象来选择目标Actor。如果没有指定策略对象,则默认选择第一个Actor。

使用示例代码:

int main() {
    ActorSystem actorSystem;

    MyActor actor1(actorSystem);
    MyActor actor2(actorSystem);

    Actor& actor1Ref = actorSystem.createActor<MyActor>();
    Actor& actor2Ref = actorSystem.createActor<MyActor>();

    RoundRobinStrategy roundRobinStrategy;
    RandomStrategy randomStrategy;

    Router roundRobinRouter(&roundRobinStrategy);
    Router randomRouter(&randomStrategy);

    actorSystem.sendMessage([&actor1]() {
        actor1.doSomething(1);
    }, &roundRobinRouter);

    actorSystem.sendMessage([&actor2]() {
        actor2.doSomething(2);
    }, &randomRouter);

    std::this_thread::sleep_for(std::chrono::seconds(5));

    actorSystem.stopActor(0);
    actorSystem.stopActor(1);

    return 0;
}

在上述示例代码中,我们创建了一个RoundRobinStrategy对象和一个RandomStrategy对象,并将它们分别传递给RoundRobinRouter和RandomRouter对象。这样,消息将根据不同的策略路由到不同的Actor上。

通过使用策略模式,我们可以很容易地添加新的路由策略,只需实现一个新的策略类,并将其传递给Router对象即可。这样,我们可以根据需要灵活地选择不同的路由策略。

动态添加/删除Actor时的路由更新

当动态添加或删除Actor时,需要更新路由策略,以确保新添加的Actor也能够接收到消息。

对于动态添加Actor,我们可以在ActorSystem类中添加一个addActor方法,用于向actors容器中添加新的Actor。在添加完Actor之后,我们需要更新路由策略对象中的Actor列表。

对于动态删除Actor,我们可以在ActorSystem类中添加一个removeActor方法,用于从actors容器中删除指定的Actor。在删除完Actor之后,我们同样需要更新路由策略对象中的Actor列表。

下面是更新后的ActorSystem类的代码:

class ActorSystem {
public:
    ActorSystem() {
        std::thread thread([this]() {
            this->run();
        });
        thread.detach();
    }

    template<typename T>
    Actor& createActor() {
        std::unique_lock<std::mutex> lock(mutex);

        Actor* actor = new Actor();
        actors.emplace(actorId, actor);
        actorId++;

        // Update routing strategy
        for (auto& strategy : routingStrategies) {
            strategy->updateActors(actors);
        }

        return *actor;
    }

    void addActor(int actorId, Actor* actor) {
        std::unique_lock<std::mutex> lock(mutex);

        actors.emplace(actorId, actor);

        // Update routing strategy
        for (auto& strategy : routingStrategies) {
            strategy->updateActors(actors);
        }
    }

    void removeActor(int actorId) {
        std::unique_lock<std::mutex> lock(mutex);

        if (actors.find(actorId) != actors.end()) {
            actors.erase(actorId);

            // Update routing strategy
            for (auto& strategy : routingStrategies) {
                strategy->updateActors(actors);
            }
        }
    }

    void sendMessage(std::function<void()> message, RoutingStrategy* strategy = nullptr) {
        std::unique_lock<std::mutex> lock(mutex);

        int actorId = -1;

        if (strategy != nullptr) {
            actorId = strategy->selectActor(actors);
        } else {
            if (!actors.empty()) {
                actorId = actors.begin()->first;
            }
        }

        if (actorId != -1) {
            actors[actorId]->send(message);
        }
    }

    void stopActor(int actorId) {
        std::unique_lock<std::mutex> lock(mutex);

        if (actors.find(actorId) != actors.end()) {
            actors[actorId]->stopActor();
            delete actors[actorId];
            actors.erase(actorId);
        }
    }

    void addRoutingStrategy(RoutingStrategy* strategy) {
        routingStrategies.push_back(strategy);
        strategy->updateActors(actors);
    }

private:
    void run() {
        while (true) {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));

            std::unique_lock<std::mutex> lock(mutex);

            for (const auto& actor : actors) {
                actor.second->run();
            }
        }
    }

    std::unordered_map<int, Actor*> actors;
    std::vector<RoutingStrategy*> routingStrategies;
    int actorId = 0;
    std::mutex mutex;
};

在更新后的ActorSystem类中,我们添加了一个routingStrategies成员变量,用于存储所有的路由策略对象。在添加或删除Actor时,我们需要遍历routingStrategies并调用每个策略对象的updateActors方法,以更新Actor列表。

此外,我们还添加了一个addRoutingStrategy方法,用于向routingStrategies中添加新的路由策略对象。在添加完路由策略对象之后,我们同样需要调用updateActors方法来更新Actor列表。

使用示例代码:

int main() {
    ActorSystem actorSystem;

    MyActor actor1(actorSystem);
    MyActor actor2(actorSystem);

    Actor& actor1Ref = actorSystem.createActor<MyActor>();
    Actor& actor2Ref = actorSystem.createActor<MyActor>();

    RoundRobinStrategy roundRobinStrategy;
    RandomStrategy randomStrategy;

    actorSystem.addRoutingStrategy(&roundRobinStrategy);
    actorSystem.addRoutingStrategy(&randomStrategy);

    actorSystem.sendMessage([&actor1]() {
        actor1.doSomething(1);
    }, &roundRobinStrategy);

    actorSystem.sendMessage([&actor2]() {
        actor2.doSomething(2);
    }, &randomStrategy);

    std::this_thread::sleep_for(std::chrono::seconds(5));

    actorSystem.stopActor(0);
    actorSystem.stopActor(1);

    return 0;
}

在上述示例代码中,我们首先创建了两个MyActor对象,并将它们添加到ActorSystem中。然后,我们创建了一个RoundRobinStrategy对象和一个RandomStrategy对象,并将它们分别添加到ActorSystem中。

接下来,我们使用sendMessage方法向不同的路由策略发送消息。在发送消息之前,我们需要将路由策略对象传递给sendMessage方法。

最后,我们停止了两个Actor,并结束了程序。在停止Actor之后,我们需要调用stopActor方法,并在ActorSystem中删除相应的Actor。

完整代码

#include <iostream>
#include <thread>
#include <chrono>
#include <unordered_map>
#include <functional>
#include <mutex>

class Actor {
public:
    Actor() {}

    void send(std::function<void()> message) {
        messages.push_back(message);
    }

    void run() {
        std::unique_lock<std::mutex> lock(mutex);

        for (const auto& message : messages) {
            message();
        }

        messages.clear();
    }

    void stopActor() {
        std::unique_lock<std::mutex> lock(mutex);

        stopped = true;
    }

private:
    std::vector<std::function<void()>> messages;
    std::mutex mutex;
    bool stopped = false;
};

class RoutingStrategy {
public:
    virtual int selectActor(const std::unordered_map<int, Actor*>& actors) = 0;
    virtual void updateActors(const std::unordered_map<int, Actor*>& actors) = 0;
};

class RoundRobinStrategy : public RoutingStrategy {
public:
    int selectActor(const std::unordered_map<int, Actor*>& actors) override {
        if (actors.empty()) {
            return -1;
        }

        if (currentActor >= actors.size()) {
            currentActor = 0;
        }

        auto it = actors.begin();
        std::advance(it, currentActor);
        currentActor++;

        return it->first;
    }

    void updateActors(const std::unordered_map<int, Actor*>& actors) override {
        this->actors = actors;
    }

private:
    std::unordered_map<int, Actor*> actors;
    int currentActor = 0;
};

class RandomStrategy : public RoutingStrategy {
public:
    int selectActor(const std::unordered_map<int, Actor*>& actors) override {
        if (actors.empty()) {
            return -1;
        }

        int randomIndex = rand() % actors.size();
        auto it = actors.begin();
        std::advance(it, randomIndex);

        return it->first;
    }

    void updateActors(const std::unordered_map<int, Actor*>& actors) override {
        this->actors = actors;
    }

private:
    std::unordered_map<int, Actor*> actors;
};

class ActorSystem {
public:
    template<typename ActorType>
    ActorType& createActor() {
        std::unique_lock<std::mutex> lock(mutex);

        ActorType* actor = new ActorType(*this);
        actors.emplace(actorId, actor);
        actorId++;

        // Update routing strategy
        for (auto& strategy : routingStrategies) {
            strategy->updateActors(actors);
        }

        return *actor;
    }

    void addActor(int actorId, Actor* actor) {
        std::unique_lock<std::mutex> lock(mutex);

        actors.emplace(actorId, actor);

        // Update routing strategy
        for (auto& strategy : routingStrategies) {
            strategy->updateActors(actors);
        }
    }

    void removeActor(int actorId) {
        std::unique_lock<std::mutex> lock(mutex);

        if (actors.find(actorId) != actors.end()) {
            actors.erase(actorId);

            // Update routing strategy
            for (auto& strategy : routingStrategies) {
                strategy->updateActors(actors);
            }
        }
    }

    void sendMessage(std::function<void()> message, RoutingStrategy* strategy = nullptr) {
        std::unique_lock<std::mutex> lock(mutex);

        int actorId = -1;

        if (strategy != nullptr) {
            actorId = strategy->selectActor(actors);
        } else {
            if (!actors.empty()) {
                actorId = actors.begin()->first;
            }
        }

        if (actorId != -1) {
            actors[actorId]->send(message);
        }
    }

    void stopActor(int actorId) {
        std::unique_lock<std::mutex> lock(mutex);

        if (actors.find(actorId) != actors.end()) {
            actors[actorId]->stopActor();
            delete actors[actorId];
            actors.erase(actorId);
        }
    }

    void addRoutingStrategy(RoutingStrategy* strategy) {
        routingStrategies.push_back(strategy);
        strategy->updateActors(actors);
    }

private:
    void run() {
        while (true) {
            std::this_thread::sleep_for(std::chrono::milliseconds(100));

            std::unique_lock<std::mutex> lock(mutex);

            for (const auto& actor : actors) {
                actor.second->run();
            }
        }
    }

    std::unordered_map<int, Actor*> actors;
    std::vector<RoutingStrategy*> routingStrategies;
    int actorId = 0;
    std::mutex mutex;
};

class MyActor {
public:
    MyActor(ActorSystem& actorSystem) : actorSystem(actorSystem) {
        actorSystem.addActor(actorId, this);
    }

    void doSomething(int value) {
        std::cout << "Actor " << actorId << " is doing something with value " << value << std::endl;
    }

private:
    int actorId;
    ActorSystem& actorSystem;
};

int main() {
    ActorSystem actorSystem;

    MyActor actor1(actorSystem);
    MyActor actor2(actorSystem);

    Actor& actor1Ref = actorSystem.createActor<MyActor>();
    Actor& actor2Ref = actorSystem.createActor<MyActor>();

    RoundRobinStrategy roundRobinStrategy;
    RandomStrategy randomStrategy;

    actorSystem.addRoutingStrategy(&roundRobinStrategy);
    actorSystem.addRoutingStrategy(&randomStrategy);

    actorSystem.sendMessage([&actor1]() {
        actor1.doSomething(1);
    }, &roundRobinStrategy);

    actorSystem.sendMessage([&actor2]() {
        actor2.doSomething(2);
    }, &randomStrategy);

    std::this_thread::sleep_for(std::chrono::seconds(5));

    actorSystem.stopActor(0);
    actorSystem.stopActor(1);

    return 0;
}


Tags:c++   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
C++常见避坑指南
C++ 从入门到放弃?本文主要总结了在C++开发或review过程中常见易出错点做了归纳总结,希望借此能增进大家对C++的了解,减少编程出错,提升工作效率,也可以作为C++开发的避坑攻略。...【详细内容】
2024-04-03  Search: c++  点击:(4)  评论:(0)  加入收藏
C++ 之父反驳白宫警告:自诞生第一天起,C++ 的目标就一直是提高安全性
整理 | 郑丽媛上个月,美国白宫国家网络主任办公室(ONCD)在一份主题为《回到基础构件:通往安全软件之路》的 19 页 PDF 报告中,呼吁开发人员停止使用容易出现内存安全漏洞的编程语...【详细内容】
2024-03-25  Search: c++  点击:(4)  评论:(0)  加入收藏
八个 C++ 开源项目,帮助初学者进阶成长
通过参与或阅读开源项目的源代码,你可以获得丰富的实践机会。实际的项目代码比简单的教程更具挑战性,可以帮助你深入理解 C++ 的各种概念和技术。1.ThreadPool一个简单的 C++1...【详细内容】
2024-03-22  Search: c++  点击:(21)  评论:(0)  加入收藏
C++多线程编程:解锁性能与并发的奥秘
今天我们将深入探讨C++中的多线程编程,揭示多线程如何解锁性能潜力,提高程序的并发性能。什么是多线程?在计算机科学中,多线程是指一个进程(程序的执行实例)中的多个线程同时执行...【详细内容】
2024-02-03  Search: c++  点击:(68)  评论:(0)  加入收藏
C++代码优化攻略
今天我们将深入探讨C++性能优化的世界。在当今软件开发的浪潮中,高性能的代码是必不可少的。无论是开发桌面应用、移动应用,还是嵌入式系统,性能都是关键。1. 选择合适的数据结...【详细内容】
2024-01-26  Search: c++  点击:(112)  评论:(0)  加入收藏
C++质数检测器的设计与实现​
质数,作为数学中的一个基本概念,一直以其独特的性质吸引着众多研究者和爱好者。质数是指大于1的自然数中,除了1和它本身以外不再有其他因数的数。在实际应用中,质数检测也扮演着...【详细内容】
2024-01-15  Search: c++  点击:(110)  评论:(0)  加入收藏
指针变量在C/C++中的内存占用
在编程领域,尤其是C和C++这类底层语言中,指针是一个核心概念,它允许程序直接操作内存地址。然而,关于指针本身在内存中占用的空间大小,却常常让初学者感到困惑。本文将深入探讨这...【详细内容】
2024-01-09  Search: c++  点击:(94)  评论:(0)  加入收藏
C++的面向对象编程:深入解析与理解
当我们谈论C++时,面向对象编程(OOP)是一个无法回避的话题。那么,C++的面向对象究竟是什么?为什么它如此重要?本文将从基本概念到实际应用,为您详细解析C++中的面向对象编程。一、面...【详细内容】
2024-01-03  Search: c++  点击:(95)  评论:(0)  加入收藏
有什么好用的C/C++源代码混淆工具?
开始使用ipaguard前言iOS加固保护是直接针对ios ipa二进制文件的保护技术,可以对iOS APP中的可执行文件进行深度混淆、加密。使用任何工具都无法逆向、破解还原源文件。对APP...【详细内容】
2023-12-29  Search: c++  点击:(117)  评论:(0)  加入收藏
C++中new与malloc:内存分配机制深度解析
本文旨在深入探讨C++中new和malloc两种内存分配机制的区别。通过对比它们在内存分配、初始化、错误处理、调用构造函数/析构函数、类型转换和使用便捷性等方面的不同,我们将...【详细内容】
2023-12-27  Search: c++  点击:(126)  评论:(0)  加入收藏
▌简易百科推荐
C++常见避坑指南
C++ 从入门到放弃?本文主要总结了在C++开发或review过程中常见易出错点做了归纳总结,希望借此能增进大家对C++的了解,减少编程出错,提升工作效率,也可以作为C++开发的避坑攻略。...【详细内容】
2024-04-03  腾讯技术工程    Tags:C++   点击:(4)  评论:(0)  加入收藏
C++ 之父反驳白宫警告:自诞生第一天起,C++ 的目标就一直是提高安全性
整理 | 郑丽媛上个月,美国白宫国家网络主任办公室(ONCD)在一份主题为《回到基础构件:通往安全软件之路》的 19 页 PDF 报告中,呼吁开发人员停止使用容易出现内存安全漏洞的编程语...【详细内容】
2024-03-25    CSDN  Tags:C++   点击:(4)  评论:(0)  加入收藏
八个 C++ 开源项目,帮助初学者进阶成长
通过参与或阅读开源项目的源代码,你可以获得丰富的实践机会。实际的项目代码比简单的教程更具挑战性,可以帮助你深入理解 C++ 的各种概念和技术。1.ThreadPool一个简单的 C++1...【详细内容】
2024-03-22  AI让生活更美好  微信公众号  Tags:C++   点击:(21)  评论:(0)  加入收藏
C# 中15个值得收藏的开源项目推荐
在开源的世界里,C# 编程语言也占有一席之地。这些开源项目涵盖了多个领域,从框架、库到工具,它们为C#开发者提供了丰富的资源和工具,帮助他们更高效地开发、测试和部署应用程序...【详细内容】
2024-03-20  程序员编程日记  微信公众号  Tags:C#   点击:(29)  评论:(0)  加入收藏
C#异步编程:Task.Run vs. async-await,掌握基础与高级用法
概述:C#中的异步编程有两主要方式:Task.Run用于在后台线程执行同步操作,而async-await更适用于清晰表达异步流程。基础用法展示了它们的简单应用,高级用法则演示了它们的结合使...【详细内容】
2024-03-09  架构师老卢  今日头条  Tags:C#   点击:(22)  评论:(0)  加入收藏
C++多线程编程:解锁性能与并发的奥秘
今天我们将深入探讨C++中的多线程编程,揭示多线程如何解锁性能潜力,提高程序的并发性能。什么是多线程?在计算机科学中,多线程是指一个进程(程序的执行实例)中的多个线程同时执行...【详细内容】
2024-02-03     AI让生活更美好  Tags:C++   点击:(68)  评论:(0)  加入收藏
C++代码优化攻略
今天我们将深入探讨C++性能优化的世界。在当今软件开发的浪潮中,高性能的代码是必不可少的。无论是开发桌面应用、移动应用,还是嵌入式系统,性能都是关键。1. 选择合适的数据结...【详细内容】
2024-01-26  AI让生活更美好  微信公众号  Tags:C++   点击:(112)  评论:(0)  加入收藏
C# 线程本地存储为什么线程间值不一样
为什么用 ThreadStatic 标记的字段,只有第一个线程拿到了初始值,其他线程都是默认值,让我能不能帮他解答一下,尼玛,我也不是神仙什么都懂,既然问了,那我试着帮他解答一下,也给后面类...【详细内容】
2024-01-26  一线码农聊技术  微信公众号  Tags:C#   点击:(66)  评论:(0)  加入收藏
C++质数检测器的设计与实现​
质数,作为数学中的一个基本概念,一直以其独特的性质吸引着众多研究者和爱好者。质数是指大于1的自然数中,除了1和它本身以外不再有其他因数的数。在实际应用中,质数检测也扮演着...【详细内容】
2024-01-15  鲨鱼编程  微信公众号  Tags:C++   点击:(110)  评论:(0)  加入收藏
C# 登顶!超越Java或非空想
整理丨诺亚出品 | 51CTO技术栈(微信号:blog51cto)近日,TIOBE编程社区公布年度编程语言,此次摘得这一桂冠的是C#。这也是C#在TIOBE二十多年评选历史中首次赢得这一年度大奖。C#虽...【详细内容】
2024-01-15    51CTO  Tags:C#   点击:(112)  评论:(0)  加入收藏
站内最新
站内热门
站内头条