时间:2022-05-25 20:33:01 | 来源:网络营销
时间:2022-05-25 20:33:01 来源:网络营销
现今,单台机器拥有多个独立的计算单元已经太常见了,这点在服务器的处理器上表现尤为明显,据AMD的一张2012-2013服务器路线图显示,服务器处理器的核心数将在2013年达到20颗之多,合理的利用CPU资源已是一个不得不考虑的问题。#include <stdio.h>这个范例比较简单,通过Actor输出了Hello Theron,需要额外说明的一点是消息在Actor之间发送时会被拷贝,接收到消息的Actor只是引用到被发送消息的一份拷贝,这么做的目的在于避免引入共享内存、同步等问题。
#include <Theron/Framework.h>
#include <Theron/Actor.h>
// 定义一个消息类型
// 在 Theron 中,任何类型都可以作为一个消息类型
// 唯一的一个约束是消息类型的变量能够被拷贝的
// 消息按值发送(而非发送它们的地址)
struct StringMessage
{
char m_string[64];
};
// 用户定义的 Actor 总需要继承于 Theron::Actor
// 每个 Actor 和应用程序的其他部分通信的唯一途径就是通过消息
class Actor : public Theron::Actor
{
public:
inline Actor()
{
// 注册消息的处理函数
RegisterHandler(this, &Actor::Handler);
}
private:
// 消息处理函数的第一个参数指定了处理的消息的类型
inline void Handler(const StringMessage& message, const Theron::Address from)
{
printf("%sn", message.m_string);
if (!Send(message, from))
printf("Failed to send message to address %dn", from.AsInteger());
}
};
int main()
{
// Framework 对象用于管理 Actors
Theron::Framework framework;
// 通过 Framework 构建一个 Actor 实例并持有其引用
// Actor 的引用类似于 Java、C# 等语言中的引用的概念
// Theron::ActorRef 采用引用计数的方式实现,类似于 boost::shared_ptr
Theron::ActorRef simpleActor(framework.CreateActor<Actor>());
// 创建一个Receiver用于接收Actor发送的消息
// 用于在非Actor代码中(例如main函数中)与Actor通信
Theron::Receiver receiver;
// 构建消息
StringMessage message;
strcpy(message.m_string, "Hello Theron!");
// 通过 Actor 的地址,我们就可以向 Actor 发送消息了
if (!framework.Send(message, receiver.GetAddress(), simpleActor.GetAddress()))
printf("Failed to send message!n");
// 等到 Actor 发送消息,避免被关闭主线程
receiver.Wait();
return 0;
}
inline void Handler(const StringMessage& message, const Theron::Address from)此Handler会不断的打印message并且带上当前Actor的地址信息,在main函数中,我们构建两个Actor实例并通过消息唤醒它们,再观察输出结果:
{
while (true)
{
printf("%s --- %dn", message.m_string, GetAddress().AsInteger());
#ifdef _MSC_VER
Sleep(1000);
#else
sleep(1);
#endif
}
}
Hello Theron! --- 1这和我们预期的一样,两个Actor实例在不同的线程下工作,实际上,Framework创建的时候会创建系统级的线程,默认情况下会创建两个(可以通过 Theron::Framework 构造函数的参数决定创建线程的数量),它们构成一个线程池,我们可以根据实际的CPU核心数来决定创建线程的数量,以确保CPU被充分利用。
Hello Theron! --- 2
Hello Theron! --- 2
Hello Theron! --- 1
Hello Theron! --- 2
Hello Theron! --- 1
Hello Theron! --- 2
Hello Theron! --- 1
......
#include <stdio.h>生产者生产物品,消费者消费物品,它们并行进行,我们没有编写创建线程的代码,没有构建共享内存,也没有处理线程的同步,这一切都很轻松的完成了。
#include <Theron/Framework.h>
#include <Theron/Actor.h>
const int PRODUCE_NUM = 5;
class Producer : public Theron::Actor
{
public:
inline Producer(): m_item(0)
{
RegisterHandler(this, &Producer::Produce);
}
private:
// 生产者生产物品
inline void Produce(const int& /* message */, const Theron::Address from)
{
int count(PRODUCE_NUM);
while (count--)
{
// 模拟一个生产的时间
#ifdef _MSC_VER
Sleep(1000);
#else
sleep(1);
#endif
printf("Produce item %dn", m_item);
if (!Send(m_item, from))
printf("Failed to send message!n");
++m_item;
}
}
// 当前生产的物品编号
int m_item;
};
class Consumer : public Theron::Actor
{
public:
inline Consumer(): m_consumeNum(PRODUCE_NUM)
{
RegisterHandler(this, &Consumer::Consume);
}
private:
inline void Consume(const int& item, const Theron::Address from)
{
// 模拟一个消费的时间
#ifdef _MSC_VER
Sleep(2000);
#else
sleep(2);
#endif
printf("Consume item %dn", item);
--m_consumeNum;
// 没有物品可以消费请求生产者进行生产
if (m_consumeNum == 0)
{
if (!Send(0, from))
printf("Failed to send message!n");
m_consumeNum = PRODUCE_NUM;
}
}
int m_consumeNum;
};
int main()
{
Theron::Framework framework;
Theron::ActorRef producer(framework.CreateActor<Producer>());
Theron::ActorRef consumer(framework.CreateActor<Consumer>());
if (!framework.Send(0, consumer.GetAddress(), producer.GetAddress()))
printf("Failed to send message!n");
// 这里使用 Sleep 来避免主线程结束
// 这样做只是为了简单而并不特别合理
// 在实际的编写中,我们应该使用Receiver
#ifdef _MSC_VER
Sleep(100000);
#else
sleep(100);
#endif
return 0;
}
关键词:思维,通过,解决