http://my.oschina.net/astute/blog/119250?p=1
在看ranch user guide的过程中,发现实现protocol handler需要使用特殊的gen_server形式,也就是enter_loop函数调用,事例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
实现ranch的protocol handler只需要实现start_link函数即可,函数中需要启动一个新的进程,新的进程需要调用accept_ack函数来绑定socket的owner进程。
如果回调要实现gen_server行为模式的话,Listener进程调用模块的start_link方法,内部同步的启动gen_server进程,并且等待gen_server进程调用init函数返回,如果这个时候在init的方法中调用accept_ack方法,就会造成循环调用,造成死锁。
ranch提供的方法如下,使用gen_server的enter_loop方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
通常情况下启动gen_server,需要调用gen_server:start_link(),参数中设置回调模块,这样的话像上面的分析,是会有死锁的问题的。
规避这个问题就是使用enter_loop方法。这个方法可以让已经存在的独立进程成为gen_server进程,在进入普通的gen_server循环之前执行设定的逻辑。
Listener进程调用proc_lib:start_link方法,创建新进程A,A执行init方法,调用proc_lib:init_ack()方法,告诉listener进程A进程已经启动,此时Listener进程就可以返回了。然后A进程再执行accept_ack()方法,最后调用enter_loop方法,让自己进入gen_server的执行循环。