根据老赵轻量级Actor进行修改的Actor模型
学习了老赵轻量级Actor模型,并在实际中使用,效果不错。
老赵轻量级Actor模型:
ActorLite:一个轻量级Actor模型实现(上)
ActorLite:一个轻量级Actor模型实现(中)
ActorLite:一个轻量级Actor模型实现(下)
但是在使用此模式的过程中,在message出队列时出现问题,出现queue.count == 0的异常,没能分析出问题的原因,暂时做了一个临时性的解决方案,也并没有测试对性能的影响。
/// <summary>
/// Actor模型接口
/// </summary>
internal interface IActor
{
/// <summary>
/// 执行
/// </summary>
void Execute();
/// <summary>
/// 退出标志
/// </summary>
bool Exited { get; }
/// <summary>
/// 消息个数
/// </summary>
int MessageCount { get; }
/// <summary>
/// Actor上下文
/// </summary>
ActorContext Context { get; }
} /// <summary>
/// Actor上下文类
/// </summary>
internal class ActorContext
{
// 表示某一时期处理消息的状态
public int Status; /// <summary>
/// 保存Actor模型类的引用
/// </summary>
public IActor Actor { get; private set; } /// <summary>
/// 构造函数
/// </summary>
/// <param name="actor"></param>
public ActorContext(IActor actor)
{
this.Actor = actor;
} // Actor模型执行状态,包括 等待、执行和退出三个状态
public const int Waiting = ;
public const int Executing = ;
public const int Exited = ;
} /// <summary>
/// Actor模型类
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class Actor<T> : IActor
{
// Actor上下文对象
private readonly ActorContext _context; // Exit flag
private bool _exited = false; // Message queue
private readonly ConcurrentQueue<T> _messageQueue = new ConcurrentQueue<T>(); /// <summary>
/// 投递消息
/// </summary>
/// <param name="message"></param>
public void Post(T message)
{
if (this._exited)
{
return;
}
this._messageQueue.Enqueue(message);
// 准备执行处理一个消息
Dispatcher.Instance.ReadyToExecute(this);
} // 接收并处理消息
protected abstract void Receive(T message); /// <summary>
/// Constructor
/// </summary>
protected Actor()
{
this._context = new ActorContext(this);
} #region Properties
/// <summary>
/// Actor上下文
/// </summary>
ActorContext IActor.Context
{
get { return this._context; }
}
/// <summary>
/// 是否退出标志
/// </summary>
bool IActor.Exited
{
get { return this._exited; }
}
/// <summary>
/// 消息队列中消息个数
/// </summary>
int IActor.MessageCount
{
get { return this._messageQueue.Count; }
}
#endregion /// <summary>
/// 处理消息
/// </summary>
void IActor.Execute()
{
T message;
var dequeueSucess = this._messageQueue.TryDequeue(out message); if (dequeueSucess)
{
this.Receive(message);
}
} protected void Start()
{
this._exited = false;
}
/// <summary>
/// 退出模式
/// </summary>
protected void Exit()
{
this._exited = true;
}
} /// <summary>
/// 分发类
/// </summary>
internal class Dispatcher
{
// Singleton
private static readonly Dispatcher _instance = new Dispatcher(); public static Dispatcher Instance
{
get { return _instance; }
} /// <summary>
/// Private Constructor
/// </summary>
private Dispatcher()
{ } /// <summary>
/// 消息预处理:设置处理状态
/// </summary>
/// <param name="actor"></param>
public void ReadyToExecute(IActor actor)
{
if (actor.Exited) return;
// 修改当前状态为执行态
int status = Interlocked.CompareExchange(ref actor.Context.Status, ActorContext.Executing, ActorContext.Waiting); if (status == ActorContext.Waiting)
{
// 线程池的可用工作线程处理消息
ThreadPool.QueueUserWorkItem(this.Execute, actor);
}
} /// <summary>
/// 消息处理
/// </summary>
/// <param name="o"></param>
private void Execute(object o)
{
IActor actor = (IActor)o;
//
actor.Execute();
// 如果退出,则设置退出标志位
if (actor.Exited)
{
Thread.VolatileWrite(ref actor.Context.Status, ActorContext.Exited);
}
// 否则进行下一个消息处理
else
{
Thread.VolatileWrite(ref actor.Context.Status, ActorContext.Waiting);
if (actor.MessageCount > )
{
this.ReadyToExecute(actor);
}
}
}
}
修改的位置:
/// <summary>
/// 处理消息
/// </summary>
void IActor.Execute()
{
T message;
var dequeueSucess = this._messageQueue.TryDequeue(out message); if (dequeueSucess)
{
this.Receive(message);
}
}
老赵原来的方式:
public void Post(T message)
{
if (this.m_exited) return; lock (this.m_messageQueue)
{
this.m_messageQueue.Enqueue(message);
} Dispatcher.Instance.ReadyToExecute(this);
}
根据老赵轻量级Actor进行修改的Actor模型的更多相关文章
- 老赵点滴地址:http://blog.zhaojie.me/2009/05/a-simple-actor-model-implementation.html
老赵点滴地址:http://blog.zhaojie.me/2009/05/a-simple-actor-model-implementation.html
- 将不确定变为确定~老赵写的CodeTimer是代码性能测试的利器
首先,非常感谢赵老大的CodeTimer,它让我们更好的了解到代码执行的性能,从而可以让我们从性能的角度来考虑问题,有些东西可能我们认为是这样的,但经理测试并非如何,这正应了我之前的那名话:“机器最能 ...
- 修改Chem 3D模型的化学键属性的方法有哪些
很多的用户在绘制化学图形过程中发现很多的图形都是立体结构的,这个时候就需要用Chem3D,它是ChemOffice的核心组件之一,在绘制立体模型和计算化学数据方面具有不可替代的作用.虽然ChemDra ...
- AF(操作者框架)系列(2)-在Actor框架中派生Actor核心(命令模式)
为了能够提高程序的复用性,我们准备用Actor Framework框架,来演示其满足了这个需求(本章及后面的内容,需要有OOP的基础知识). 首先,简述一下ActorFramework的运行过程: 在 ...
- (转).net面试题(老赵)
转自:http://www.cnblogs.com/chenxiaoran/archive/2012/05/27/2519988.html 1.什么是CLR 公共语言运行时(Comman langua ...
- actor、reactor与proactor模型:高性能服务器的几种模型概念(转)
actor模型: 实体之通过消息通讯,各自处理自己的数据,能够实现这并行. 说白了,有点像rpc. skynet是actor模型. reactor模型: 1 向事件分发器注册事件回调 2 事件发生 4 ...
- pytorch中修改后的模型如何加载预训练模型
问题描述 简单来说,比如你要加载一个vgg16模型,但是你自己需要的网络结构并不是原本的vgg16网络,可能你删掉某些层,可能你改掉某些层,这时你去加载预训练模型,就会报错,错误原因就是你的模型和原本 ...
- 专业上的常用的工具和类库集 By 老衣
Visual Studio 2013 扩展 CodeMaid: 可快速整理代码文件,清理不必要的代码和杂乱的格式.并在开发时实时提供代码复杂度的报告,以便帮助开发人员降低代码复杂度.提高代码质量. C ...
- 进程、线程、轻量级进程、协程与 go 的 goroutine【转载+整理】
本文内容 进程 线程 协程 Go 中的 goroutine 参考资料 最近,看一些文章,提到"协程"的概念,心想,进程,线程,协程,前两个很容易,任何一本关于操作系统的书都有说,开 ...
随机推荐
- Linux启动新进程的几种方法及比较
有时候,我们需要在自己的程序(进程)中启动另一个程序(进程)来帮助我们完成一些工作,那么我们需要怎么才能在自己的进程中启动其他的进程呢?在Linux中提供了不少的方法来实现这一点,下面就来介绍一个这些 ...
- 【机房系统知识小结点系列】之遍历窗体中的控件,判断Text是否为空?
做机房系统时,几乎每个窗体中都会用到判断界面中的控件是否为空的情景.我们曾经是这样走来的: 第一版: 好处:对窗体界面中的Text等控件,逐一做判断,当用户输入某一项为空的时候,会议弹出框的形式,告诉 ...
- opengl笔记—— glMultMatrixf() 区别 glLoadMatrixf()
能找到最好的解释来自:http://www.gamedev.net/topic/489879-glpushmatrixglpopmatrix--glloadmatrixf/ 原理: glPushMat ...
- 多进程用户并发处理Demo(C#版)
这个示例主要演示的是在多进程操作数据库时,如何避免并发重复数据入库的例子. 过多的线程理论不再阐述,网上.书上皆有. 项目采用 Asp.Net Framework 4.5 / Mysql 5.4 数据 ...
- 白话JAVA守护线程
OneCoder(苦逼Coder)原创,转载请务必注明出处: http://www.coderli.com/archives/daemon-thread-plain-words/ 关于“白话”:偶然想 ...
- php get_magic_quotes_gpc() addslashes()
最近学了学PHP,看到这段代码 function daddslashes($str){ return (!get_magic_quotes_gpc())?addslashes($str): ...
- html加载js那些事
浏览器通过内置的JavaScript引擎,读取网页中的代码,对其处理后运行. JavaScript代码嵌入网页的方法 在网页中嵌入JavaScript代码有多种方法. 直接添加代码块 通过script ...
- MAVEN项目,Eclipse启动报错:java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
由于是maven项目,tomcat在发布项目的时候没有同时发布maven依赖所添加的jar包,所以报此错误: 解决办法: 项目右键 —> 属性 -> Deployment Assembly ...
- Linux下如何查看哪些进程占用的CPU内存资源最多
linux下获取占用CPU资源最多的10个进程,可以使用如下命令组合: ps aux|head -1;ps aux|grep -v PID|sort -rn -k +3|head linux下获取占用 ...
- js获取时间和日期,字符串和时间戳之间的转换
//获取当前时间: var myDate = new Date();//当前时间 var year = myDate.getFullYear();//当前年份 var month = myDate.g ...