Archive for the ‘Erlang’ tag
消息流的方向
- 哪些消息的产生只能在某个模块产生。
- 对于需要进行资源分配的消息更是要慎重,需要制定分配在那个模块出现,而解构在哪个模块进行,一般比较合适的做法是将对于同一种资源的分配和释放放在同一个模块中。
- 模块之间有没有层次性,哪些模块永远处于一个消费者、被动的地步。
…需要有一个从进程管理模块到进程间通信模块的信息通信链,具体的做法就是当进程管理模块在感知到某个进程收到信号的时候先发消息到虚拟内存管理模块,然后由虚拟内存管理模块再发送到进程间通信模块。上述只是粗线条的描述,细节就是当虚拟内存管理模块发送到进程间通信模块的时候,不能直接使用send函数发送消息,而是必须先要利用notify函数通知这个进程间通信模块,使得该模块了解到当前进程的状态发生了改变,因为notify的内在机制是非阻塞的,而send则有可能阻塞,因而当两个进程互相发送消息时,就有可能导致死锁的发生。这里就需要有一个从进程管理模块到进程间通信模块的信息通信链,具体的做法就是当进程管理模块在感知到某个进程收到信号的时候先发消息到虚拟内存管理模块,然后由虚拟内存管理模块再发送到进程间通信模块。上述只是粗线条的描述,细节就是当虚拟内存管理模块发送到进程间通信模块的时候,不能直接使用send函数发送消息,而是必须先要利用notify函数通知这个进程间通信模块,使得该模块了解到当前进程的状态发生了改变,因为notify的内在机制是非阻塞的,而send则有可能阻塞,因而当两个进程互相发送消息时,就有可能导致死锁的发生。
这里还有一个需要注意的地方,因为进程间通信模块是动态启动的,所以它的endpoint无法预先获知,当然,它的endpoint值可以通过数据存储管理模块来获得。按照最早的实现,虚拟内存管理模块在收到进程管理模块的时候先去查询数据存储管理服务器,但问题恰恰出在这里:进程管理模块,虚拟内存管理模块,数据存储管理模块这三个模块之间会导致死锁。
最终的选择就是在进程管理模块中预先获知进程间通信模块的endpoint的值,然后封装成一个消息一起发送到虚拟内存管理模块,这样虚拟内存管理服务器就可以直接发送到正确的进程间通信服务器,而不需要再去查询数据存储管理服务器。进程间通信模块在获得了notify消息之后,反过来查询虚拟内存管理服务器,获得正确的进程将要退出的消息之后将这些进程从等待的队列上解除。
这里其实说明了消息传递方向的重要性,消息流动的主题方向是从用户进程到库函数,再到文件系统,虚拟内存模块,最终如果有机会的话被传递到底层的内核中。如下图所示:
如果两个部分在消息传递上产生了产生了互相依赖的情况,那么就会产生回环,就可能会在系统的运行过程中产生死锁。
Erlang初识
上个帖子说道“Vmware收了rabbitmq”,不知道列位看官对RabbitMq有否了解,这是一个用Erlang编写的消息传递系统,因此,大嘴牛就在这里八一八Erlang。
Erlang就像一个待字闺中的千金大小姐,虽然很早就已经发明了,但是人们很少提起她的名字,直到最近的几年,这位大小姐突然在T型舞台上show了一把,直引得各路神仙为之而轻狂。
这种成功应该算是一种必然,当计算机的功能越来越强大,多核成为一种时尚的时候,轻便的线程机制、内建的快捷通信机制则成为了解决高并发、多线程的杀手利器。
大嘴牛趁着这个五一在家,也算初始了这个Erlang小姐,有幸一睹尊容,下面是大嘴牛对于这位小姐的第一感觉:
IO格式化与Lisp大小姐长得很像,比如都是通过~n来表示下一行,这时候C反而变得有些另类。
Erlang中的等号(=)表示的模式匹配的含义,而不是普通编程语言中的赋值概念。就这一点来看,她和Prolog大小姐也有血缘关系,从Erlang的历史可以知道,Erlang的早期实现版本就是通过Prolog来写就的,因此也就难怪举止间透着同样的气质。
Erlang的列表表示与Lisp的列表可以说十分接近,使用的理解也十分相同。在Erlang中,我们使用[H | T]来解析出列表的头与尾;而在Lisp中,我们则是通过car与cdr。简直就是一个磨子里刻出来的。
第一感觉,纯属第一感觉,如果有谁有幸和Erlang小姐签过手,甚至搂抱过的,还请贻笑大方了。
大嘴牛也一定要和Erlang谈场恋爱的说。