時(shí)間:2022-05-25 20:33:01 | 來源:網(wǎng)絡(luò)營(yíng)銷
時(shí)間:2022-05-25 20:33:01 來源:網(wǎng)絡(luò)營(yíng)銷
現(xiàn)今,單臺(tái)機(jī)器擁有多個(gè)獨(dú)立的計(jì)算單元已經(jīng)太常見了,這點(diǎn)在服務(wù)器的處理器上表現(xiàn)尤為明顯,據(jù)AMD的一張2012-2013服務(wù)器路線圖顯示,服務(wù)器處理器的核心數(shù)將在2013年達(dá)到20顆之多,合理的利用CPU資源已是一個(gè)不得不考慮的問題。#include <stdio.h>這個(gè)范例比較簡(jiǎn)單,通過Actor輸出了Hello Theron,需要額外說明的一點(diǎn)是消息在Actor之間發(fā)送時(shí)會(huì)被拷貝,接收到消息的Actor只是引用到被發(fā)送消息的一份拷貝,這么做的目的在于避免引入共享內(nèi)存、同步等問題。
#include <Theron/Framework.h>
#include <Theron/Actor.h>
// 定義一個(gè)消息類型
// 在 Theron 中,任何類型都可以作為一個(gè)消息類型
// 唯一的一個(gè)約束是消息類型的變量能夠被拷貝的
// 消息按值發(fā)送(而非發(fā)送它們的地址)
struct StringMessage
{
char m_string[64];
};
// 用戶定義的 Actor 總需要繼承于 Theron::Actor
// 每個(gè) Actor 和應(yīng)用程序的其他部分通信的唯一途徑就是通過消息
class Actor : public Theron::Actor
{
public:
inline Actor()
{
// 注冊(cè)消息的處理函數(shù)
RegisterHandler(this, &Actor::Handler);
}
private:
// 消息處理函數(shù)的第一個(gè)參數(shù)指定了處理的消息的類型
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 對(duì)象用于管理 Actors
Theron::Framework framework;
// 通過 Framework 構(gòu)建一個(gè) Actor 實(shí)例并持有其引用
// Actor 的引用類似于 Java、C# 等語言中的引用的概念
// Theron::ActorRef 采用引用計(jì)數(shù)的方式實(shí)現(xiàn),類似于 boost::shared_ptr
Theron::ActorRef simpleActor(framework.CreateActor<Actor>());
// 創(chuàng)建一個(gè)Receiver用于接收Actor發(fā)送的消息
// 用于在非Actor代碼中(例如main函數(shù)中)與Actor通信
Theron::Receiver receiver;
// 構(gòu)建消息
StringMessage message;
strcpy(message.m_string, "Hello Theron!");
// 通過 Actor 的地址,我們就可以向 Actor 發(fā)送消息了
if (!framework.Send(message, receiver.GetAddress(), simpleActor.GetAddress()))
printf("Failed to send message!n");
// 等到 Actor 發(fā)送消息,避免被關(guān)閉主線程
receiver.Wait();
return 0;
}
inline void Handler(const StringMessage& message, const Theron::Address from)此Handler會(huì)不斷的打印message并且?guī)袭?dāng)前Actor的地址信息,在main函數(shù)中,我們構(gòu)建兩個(gè)Actor實(shí)例并通過消息喚醒它們,再觀察輸出結(jié)果:
{
while (true)
{
printf("%s --- %dn", message.m_string, GetAddress().AsInteger());
#ifdef _MSC_VER
Sleep(1000);
#else
sleep(1);
#endif
}
}
Hello Theron! --- 1這和我們預(yù)期的一樣,兩個(gè)Actor實(shí)例在不同的線程下工作,實(shí)際上,F(xiàn)ramework創(chuàng)建的時(shí)候會(huì)創(chuàng)建系統(tǒng)級(jí)的線程,默認(rèn)情況下會(huì)創(chuàng)建兩個(gè)(可以通過 Theron::Framework 構(gòu)造函數(shù)的參數(shù)決定創(chuàng)建線程的數(shù)量),它們構(gòu)成一個(gè)線程池,我們可以根據(jù)實(shí)際的CPU核心數(shù)來決定創(chuàng)建線程的數(shù)量,以確保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>生產(chǎn)者生產(chǎn)物品,消費(fèi)者消費(fèi)物品,它們并行進(jìn)行,我們沒有編寫創(chuàng)建線程的代碼,沒有構(gòu)建共享內(nèi)存,也沒有處理線程的同步,這一切都很輕松的完成了。
#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:
// 生產(chǎn)者生產(chǎn)物品
inline void Produce(const int& /* message */, const Theron::Address from)
{
int count(PRODUCE_NUM);
while (count--)
{
// 模擬一個(gè)生產(chǎn)的時(shí)間
#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;
}
}
// 當(dāng)前生產(chǎn)的物品編號(hào)
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)
{
// 模擬一個(gè)消費(fèi)的時(shí)間
#ifdef _MSC_VER
Sleep(2000);
#else
sleep(2);
#endif
printf("Consume item %dn", item);
--m_consumeNum;
// 沒有物品可以消費(fèi)請(qǐng)求生產(chǎn)者進(jìn)行生產(chǎn)
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 來避免主線程結(jié)束
// 這樣做只是為了簡(jiǎn)單而并不特別合理
// 在實(shí)際的編寫中,我們應(yīng)該使用Receiver
#ifdef _MSC_VER
Sleep(100000);
#else
sleep(100);
#endif
return 0;
}
關(guān)鍵詞:思維,通過,解決
客戶&案例
營(yíng)銷資訊
關(guān)于我們
客戶&案例
營(yíng)銷資訊
關(guān)于我們
微信公眾號(hào)
版權(quán)所有? 億企邦 1997-2022 保留一切法律許可權(quán)利。