C++ 并发编程的一种思维
作者:网络转载 发布时间:[ 2012/11/28 10:29:26 ] 推荐标签:
这个范例比较简单,通过 Actor 输出了 Hello Theron。需要额外说明的一点是消息在 Actor 之间发送时会被拷贝,接收到消息的 Actor 只是引用到被发送消息的一份拷贝,这么做的目的在于避免引入共享内存、同步等问题。
Theron 的消息处理
前面谈到过,每个 Actor 都工作在一个属于自己的“线程”上,我们通过一个例子来认识这一点,我们修改上面例子中的 Actor:: Handler 成员方法:
inline void Handler(const StringMessage& message, const Theron::Address from)
{
while (true)
{
printf("%s --- %d
", message.m_string, GetAddress().AsInteger());
#ifdef _MSC_VER
Sleep(1000);
#else
sleep(1);
#endif
}
}
此 Handler 会不断的打印 message 并且带上当前 Actor 的地址信息。在 main 函数中,我们构建两个 Actor 实例并通过消息唤醒它们,再观察输出结果:
Hello Theron! --- 1
Hello Theron! --- 2
Hello Theron! --- 2
Hello Theron! --- 1
Hello Theron! --- 2
Hello Theron! --- 1
Hello Theron! --- 2
Hello Theron! --- 1
......
这和我们预期的一样,两个 Actor 实例在不同的线程下工作。实际上,Framework 创建的时候会创建系统级的线程,默认情况下会创建两个(可以通过 Theron::Framework 构造函数的参数决定创建线程的数量),它们构成一个线程池,我们可以根据实际的 CPU 核心数来决定创建线程的数量,以确保 CPU 被充分利用。线程池的线程是以何种方式进行调度的?如下图:
接收到消息的 Actor 会被放置于一个线程安全的 Work 队列中,此队列中的 Actor 会被唤醒的工作线程取出,并进行消息的处理。这个过程中有两个需要注意的地方:
1、对于某个 Actor 我们可以为某个消息类型注册多个消息处理函数,那么此消息类型对应的多个消息处理函数会按照注册的顺序被串行执行下去
2、线程按顺序处理 Actor 收到的消息,一个消息未处理完成不会处理消息队列中的下一个消息 我们可以想象,如果存在三个 Actor,其中两个 Actor 的消息处理函数中存在死循环(例如上例中的 while(true)),那么它们一旦执行会霸占两条线程,若线程池中没有多余线程,那么另一个 Actor 将被“饿死”(永远得不到执行)。我们可以在设计上避免这种 Actor 的出现,当然也可以适当的调整线程池的大小来解决此问题。Theron 中,线程池中线程的数量是可以动态控制的,线程利用率也可以测量。但是务必注意的是,过多的线程必然导致过大的线程上下文切换开销。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11