??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产成人精品久久久国产成人一区二区三区综 ,一个色综合久久,精品视频久久久久http://www.shnenglu.com/keigoliye/category/11700.html一切都是纸老虎zh-cnWed, 09 Dec 2009 13:29:16 GMTWed, 09 Dec 2009 13:29:16 GMT60erlang?009-12-7日关于用其他语言实现erlang模式的聊天记?/title><link>http://www.shnenglu.com/keigoliye/archive/2009/12/07/102764.html</link><dc:creator>暗夜教父</dc:creator><author>暗夜教父</author><pubDate>Mon, 07 Dec 2009 15:49:00 GMT</pubDate><guid>http://www.shnenglu.com/keigoliye/archive/2009/12/07/102764.html</guid><wfw:comment>http://www.shnenglu.com/keigoliye/comments/102764.html</wfw:comment><comments>http://www.shnenglu.com/keigoliye/archive/2009/12/07/102764.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/keigoliye/comments/commentRss/102764.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/keigoliye/services/trackbacks/102764.html</trackback:ping><description><![CDATA[2009-12-7 22:19:36 LinkTalk.NET(909327571)<br>暗夜教父Q?你说?万连接,每个q接每秒?K包吗Q?br><br>2009-12-7 22:19:49 暗夜教父(199033)<br>en <br><br>2009-12-7 22:19:49 jack(357794482)<br>是后面函数执行完成之后的结果给前面的原子吗 <br><br>2009-12-7 22:20:54 LinkTalk.NET(909327571)<br>机器配置如何Q还?万个客户端如何模拟的Q?br><br>2009-12-7 22:21:41 暗夜教父(199033)<br>机器是AMD 双核 3200+<br><br>2009-12-7 22:21:50 LinkTalk.NET(909327571)<br>另外是每个q接上的旉间隔?U,没有延迟吗?<br><br>2009-12-7 22:22:12 暗夜教父(199033)<br>内存?GQ操作系lubuntu 9.10<br><br>2009-12-7 22:22:53 暗夜教父(199033)<br>我h为的没做q种延迟<br><br>2009-12-7 22:23:04 暗夜教父(199033)<br>服务器和客户端都是这个配|?br><br>2009-12-7 22:23:16 暗夜教父(199033)<br>客户端是用erlang模拟q发<br><br>2009-12-7 22:23:39 暗夜教父(199033)<br>不过创徏6W个连接花费了一定的旉<br><br>2009-12-7 22:24:09 暗夜教父(199033)<br>对哦Q这样就不是6万个一起ƈ发出来的<br><br>2009-12-7 22:24:09 LinkTalk.NET(909327571)<br>大概多久Q?br><br>2009-12-7 22:24:19 暗夜教父(199033)<br>没统计时?br><br>2009-12-7 22:24:42 暗夜教父(199033)<br>q里存在问题?br><br>2009-12-7 22:25:27 暗夜教父(199033)<br>其实q发应该?q接?/ 创徏q发的时?br><br>2009-12-7 22:25:27 LinkTalk.NET(909327571)<br>什么问题?<br><br>2009-12-7 22:25:49 LinkTalk.NET(909327571)<br>q个无所?br><br>2009-12-7 22:26:08 LinkTalk.NET(909327571)<br>只要你全部连接创建好后一直保持住可以了<br><br>2009-12-7 22:26:23 暗夜教父(199033)<br>一直保持也不是6万同?br><br>2009-12-7 22:26:32 暗夜教父(199033)<br>创徏q接有时?br><br>2009-12-7 22:26:35 LinkTalk.NET(909327571)<br>6万个如果能够1k/s的保?8时的话Q非常牛g<br><br>2009-12-7 22:26:38 暗夜教父(199033)<br>那么发生数据也有时差<br><br>2009-12-7 22:27:53 LinkTalk.NET(909327571)<br>你通过什么方式做到间隔一U发一ơ数据的Q?br><br>2009-12-7 22:28:32 LinkTalk.NET(909327571)<br>sleep吗?<br><br>2009-12-7 22:29:19 LinkTalk.NET(909327571)<br>你有没有看一下网卡的带宽消?br><br>2009-12-7 22:29:37 LinkTalk.NET(909327571)<br>按道理应?k * 6?= 60M/s<br><br>2009-12-7 22:30:12 LinkTalk.NET(909327571)<br>如果辑ֈ60M以上基本是真正的稳定的实现?万ƈ?br><br>2009-12-7 22:30:34 暗夜教父(199033)<br>client那边是我同事写的<br><br>2009-12-7 22:30:39 暗夜教父(199033)<br>我不知道是不是sleep<br><br>2009-12-7 22:30:52 暗夜教父(199033)<br>带宽消耗我q也真没?br><br>2009-12-7 22:30:53 LinkTalk.NET(909327571)<br>erlang里面好像也就只有sleep?br><br>2009-12-7 22:31:06 暗夜教父(199033)<br>我估计不?br><br>2009-12-7 22:31:52 LinkTalk.NET(909327571)<br>另外我怀疑当q发高了以后Qsleep会不准,真正的间隔肯定会大于sleep的时?br><br>2009-12-7 22:32:50 暗夜教父(199033)<br>恩,实有待验证<br><br>2009-12-7 22:33:04 暗夜教父(199033)<br>不过只有用应用来验证?br><br>2009-12-7 22:33:14 暗夜教父(199033)<br>{项目上U了Q看看实际情?br><br>2009-12-7 22:33:17 LinkTalk.NET(909327571)<br>嗯,呵呵<br><br>2009-12-7 22:33:24 LinkTalk.NET(909327571)<br>你们q个用在什么项目上马?<br><br>2009-12-7 22:33:27 LinkTalk.NET(909327571)<br>上面<br><br>2009-12-7 22:33:30 LinkTalk.NET(909327571)<br>游戏吗?<br><br>2009-12-7 22:33:31 暗夜教父(199033)<br>恩,游戏?br><br>2009-12-7 22:34:48 LinkTalk.NET(909327571)<br>[表情]<br><br>2009-12-7 22:34:59 暗夜教父(199033)<br>不过风险也很?br><br>2009-12-7 22:35:15 LinkTalk.NET(909327571)<br>Z么?<br><br>2009-12-7 22:35:24 暗夜教父(199033)<br>没做q?br><br>2009-12-7 22:35:28 暗夜教父(199033)<br>没有成熟目的经?br><br>2009-12-7 22:35:29 LinkTalk.NET(909327571)<br>呵呵<br><br>2009-12-7 22:35:32 暗夜教父(199033)<br>什么都有可能发?br><br>2009-12-7 22:35:45 LinkTalk.NET(909327571)<br>传统的游戏服务器Q单台到两三万ƈ发已l很牛X?br><br>2009-12-7 22:35:50 暗夜教父(199033)<br>未知因素太多<br><br>2009-12-7 22:36:00 暗夜教父(199033)<br>我估?Wq能?br><br>2009-12-7 22:36:00 LinkTalk.NET(909327571)<br>而且gq不差的情况?br><br>2009-12-7 22:36:11 LinkTalk.NET(909327571)<br>游戏的数据通信量比较大<br><br>2009-12-7 22:36:22 LinkTalk.NET(909327571)<br>?br><br>2009-12-7 22:36:30 暗夜教父(199033)<br>没过6W是因为客L的端口基本上没了<br><br>2009-12-7 22:36:45 LinkTalk.NET(909327571)<br>q个不会?br><br>2009-12-7 22:36:51 LinkTalk.NET(909327571)<br>客户端端口没有关pȝ<br><br>2009-12-7 22:36:55 暗夜教父(199033)<br>有吧<br><br>2009-12-7 22:36:59 LinkTalk.NET(909327571)<br>因ؓIP不一?br><br>2009-12-7 22:37:11 暗夜教父(199033)<br>不是。我试的时?br><br>2009-12-7 22:37:15 LinkTalk.NET(909327571)<br>同一个IP?5535个端口的限制<br><br>2009-12-7 22:37:18 暗夜教父(199033)<br>6万个q接从一台机器来?br><br>2009-12-7 22:37:18 LinkTalk.NET(909327571)<br>哦,了解<br><br>2009-12-7 22:37:23 LinkTalk.NET(909327571)<br>?br><br>2009-12-7 22:37:54 david(258667581)<br>服务器端只监听一个端?应该不会有端口数限制吧?<br><br>2009-12-7 22:38:24 LinkTalk.NET(909327571)<br>服务器端不会<br><br>2009-12-7 22:38:50 david(258667581)<br>做游戏的?不是都雍和宫服务器吗<br><br>2009-12-7 22:38:55 david(258667581)<br>都做的服务器?br><br>2009-12-7 22:39:24 暗夜教父(199033)<br>。。?br><br>2009-12-7 22:39:32 暗夜教父(199033)<br>我是做测?br><br>2009-12-7 22:39:36 david(258667581)<br>另外 如果端口socket属性设|reuse为true 是否可以过6W端口<br><br>2009-12-7 22:39:48 LinkTalk.NET(909327571)<br>不会<br><br>2009-12-7 22:39:53 暗夜教父(199033)<br>服务器端是一台机器,客户端也是一台机?br><br>2009-12-7 22:39:56 LinkTalk.NET(909327571)<br>那个是针对不同的protocol<br><br>2009-12-7 22:40:02 暗夜教父(199033)<br>客户端发?W个连?br><br>2009-12-7 22:40:19 暗夜教父(199033)<br>p占用6W多个端口<br><br>2009-12-7 22:40:18 david(258667581)<br>不同的protocol是什么意?br><br>2009-12-7 22:40:35 LinkTalk.NET(909327571)<br>tcp ?udp 可以reuse同一个port<br><br>2009-12-7 22:41:09 LinkTalk.NET(909327571)<br>erlang其实我只是大概的了解<br><br>2009-12-7 22:41:22 LinkTalk.NET(909327571)<br>我打用C#和Java模拟erlang<br><br>2009-12-7 22:41:26 david(258667581)<br>E序a试用端口2000 tcpq?然后 E序b?000端口udp再连接另外一个程序?<br><br>2009-12-7 22:41:36 david(258667581)<br>模拟Q?br><br>2009-12-7 22:41:40 LinkTalk.NET(909327571)<br>?br><br>2009-12-7 22:41:47 LinkTalk.NET(909327571)<br>我已l用C#实现?br><br>2009-12-7 22:41:47 david(258667581)<br>怎么模拟Q?br><br>2009-12-7 22:41:59 LinkTalk.NET(909327571)<br>是Actor模式<br><br>2009-12-7 22:42:07 LinkTalk.NET(909327571)<br>自己实现消息的调?br><br>2009-12-7 22:42:15 LinkTalk.NET(909327571)<br>q有实现异步~程接口<br><br>2009-12-7 22:42:41 david(258667581)<br>actor模式是什么意?br><br>2009-12-7 22:42:59 LinkTalk.NET(909327571)<br>一UY件设计模?br><br>2009-12-7 22:43:16 LinkTalk.NET(909327571)<br>erlang/scala{ƈ发^台都是actor模式<br><br>2009-12-7 22:44:06 david(258667581)<br>不懂<br><br>2009-12-7 22:44:25 david(258667581)<br>Z么要用c#模拟Q?br><br>2009-12-7 22:44:33 LinkTalk.NET(909327571)<br>因ؓ我熟悉C#<br><br>2009-12-7 22:44:39 LinkTalk.NET(909327571)<br>也打用java模拟<br><br>2009-12-7 22:45:01 LinkTalk.NET(909327571)<br>同时也因为C#/Java有大量的开发h员和丰富的第三方扩展<br><br>2009-12-7 22:45:25 LinkTalk.NET(909327571)<br>同时也有很爽的IDE<br><br>2009-12-7 22:45:26 LinkTalk.NET(909327571)<br>Q)<br><br>2009-12-7 22:45:42 david(258667581)<br>?但是感觉如果你是要测性能的话 c#的性能可能跟不上erlang?br><br>2009-12-7 22:45:49 david(258667581)<br>用c的都会好?br><br>2009-12-7 22:46:01 LinkTalk.NET(909327571)<br>其实erlang语言本n性能不见得高Q因为是脚本语言<br><br>2009-12-7 22:46:15 LinkTalk.NET(909327571)<br>高ƈ发是因ؓU消息传递,可以有效的避免死?br><br>2009-12-7 22:46:27 LinkTalk.NET(909327571)<br>传统语言比如c/c++要避免死锁比较难<br><br>2009-12-7 22:46:49 LinkTalk.NET(909327571)<br>l大家看老外的一个测试数?br><br>2009-12-7 22:46:57 LinkTalk.NET(909327571)<br>erlang其实是执行效率相对比较差的<br><br>2009-12-7 22:47:20 david(258667581)<br>哪里 erlang的性能应该是可以跟c叫板?br><br>2009-12-7 22:48:04 LinkTalk.NET(909327571)<br>http://shootout.alioth.debian.org/u32q/benchmark.php?test=all&lang=csharp&lang2=hipe&box=1<br><br>2009-12-7 22:48:16 LinkTalk.NET(909327571)<br>q个里面有很多语a的性能试比较<br><br>2009-12-7 22:48:23 LinkTalk.NET(909327571)<br>erlang是比较差的<br><br>2009-12-7 22:49:02 LinkTalk.NET(909327571)<br>传统语言达不到高q发是因为无法有效的避免死锁Q还有cpu调度做得不好<br><br>2009-12-7 22:50:17 暗夜教父(199033)<br>恩,C如果使用erlang的模?br><br>2009-12-7 22:50:26 暗夜教父(199033)<br>l对不会?br><br>2009-12-7 22:50:29 LinkTalk.NET(909327571)<br>?br><br>2009-12-7 22:50:37 LinkTalk.NET(909327571)<br>erlang本n是C写的<br><br>2009-12-7 22:50:41 暗夜教父(199033)<br>?br><br>2009-12-7 22:50:54 LinkTalk.NET(909327571)<br>我记得国内好像有个牛人在研究用C++模拟erlang<br><br>2009-12-7 22:51:00 LinkTalk.NET(909327571)<br>好像是盛大的一个架构师<br><br>2009-12-7 22:51:13 暗夜教父(199033)<br>貌似现在做linux下做服务器端得,C比C++多了<br><br>2009-12-7 22:51:20 LinkTalk.NET(909327571)<br>?br><br>2009-12-7 22:51:29 LinkTalk.NET(909327571)<br>linux下c?br><br>2009-12-7 22:51:36 暗夜教父(199033)<br>我记得好像云风把大话西游的服务器端改成C?br><br>2009-12-7 22:52:28 生啊牙(86753957)<br>51.com的服务器是用C++模拟erlang?br><br>2009-12-7 22:52:50 生啊牙(86753957)<br>使用协程<br><br>2009-12-7 22:53:59 LinkTalk.NET(909327571)<br>嗯,协程可以在传l的面向q程的线E上模拟异步操作<br><br>2009-12-7 22:55:05 LinkTalk.NET(909327571)<br>其实高ƈ发只是一U设计模?br><br>2009-12-7 22:55:19 LinkTalk.NET(909327571)<br>erlang把这个设计模式固化ƈ强制到语法里?br><br>2009-12-7 22:56:22 LinkTalk.NET(909327571)<br>C#2.0开始有个新的特性,叫iteratorQ通过yield关键字来实现coroutineQ协E)<br><br>2009-12-7 22:56:39 LinkTalk.NET(909327571)<br>q且在语法上也可以用q诏的Ş式来实现异步的操?br><br>2009-12-7 22:56:49 LinkTalk.NET(909327571)<br>和erlang的Ş式类?br><br>2009-12-7 22:57:10 LinkTalk.NET(909327571)<br>java里面目前只有anonymous class可以实现异步调用<br><br>2009-12-7 22:57:44 LinkTalk.NET(909327571)<br>但是那个语法写v来有些牵强,花括号会嵌深<br><br>2009-12-7 22:59:19 LinkTalk.NET(909327571)<br>我用C#实现的actor模式也可以处理每分钟大概200万条消息Q在PC上)<br><br>2009-12-7 22:59:24 LinkTalk.NET(909327571)<br>AMD双核<br><br>2009-12-7 23:00:28 LinkTalk.NET(909327571)<br>也测试过HTTP hQ大概可以达?万多q发Q不q是6U一个请求(sleep6U,实际会gq到10U以上)Qcpu占用40-60<br><br>2009-12-7 23:01:54 LinkTalk.NET(909327571)<br>每分?00万消息是最单的ping/pong试<br><br>2009-12-7 23:06:12 david(258667581)<br>以前没听说过 协程 呵呵<br><br>2009-12-7 23:06:33 LinkTalk.NET(909327571)<br>是否有协E无所谓的<br><br>2009-12-7 23:07:14 LinkTalk.NET(909327571)<br>关键是纯消息传递(避免死锁Q还有线E合理有效的调度Q实现高效的异步处理Q?br><br>2009-12-7 23:07:35 david(258667581)<br>?关键是避开?br><br>2009-12-7 23:08:04 LinkTalk.NET(909327571)<br>q最好再能够在语法上异步操作用序化的代码来表C?br><br>2009-12-7 23:08:22 LinkTalk.NET(909327571)<br>实在不行也无所谓,可以用event handler的方?br><br>2009-12-7 23:08:48 david(258667581)<br>能否举一个异步操作的具体应用场景Q?br><br>2009-12-7 23:09:08 LinkTalk.NET(909327571)<br>很多都是异步操作Q那样IO才可以做到高效)<br><br>2009-12-7 23:09:19 LinkTalk.NET(909327571)<br>比如epoll和windows的iocp<br><br>2009-12-7 23:09:22 LinkTalk.NET(909327571)<br>都是异步?br><br>2009-12-7 23:09:44 LinkTalk.NET(909327571)<br>单的原理是调用函数递交或注册一个IOh到系l内?br><br>2009-12-7 23:09:45 david(258667581)<br>是不是都是底层的<br><br>2009-12-7 23:09:55 LinkTalk.NET(909327571)<br>然后不需要阻塞,立即q回<br><br>2009-12-7 23:10:17 LinkTalk.NET(909327571)<br>pȝIO内核收到数据或相关的事g会触发当初注册的回调函数<br><br>2009-12-7 23:10:59 LinkTalk.NET(909327571)<br>调用h ?数据q回或事件触?不在同一个操作系l线E上完成Q就UCؓ异步<br><br>2009-12-7 23:11:13 LinkTalk.NET(909327571)<br>异步的IO才比较高?br><br>2009-12-7 23:11:37 LinkTalk.NET(909327571)<br>操作pȝ的线E数有限?br><br>2009-12-7 23:11:42 david(258667581)<br>q些都不?无论是java和c#q是cQ都已经有专门的api支撑?br><br>2009-12-7 23:11:51 david(258667581)<br>关键是业务上的操?<br><br>2009-12-7 23:11:55 LinkTalk.NET(909327571)<br>一般上了千以后Q线E的效率比较差?br><br>2009-12-7 23:11:58 david(258667581)<br>锁的都是业务<br><br>2009-12-7 23:12:02 LinkTalk.NET(909327571)<br>而且很耗cpu和内?br><br>2009-12-7 23:12:23 LinkTalk.NET(909327571)<br>所以要通过合理的调度和异步操作来分享宝늚操作pȝU程<br><br>2009-12-7 23:12:51 LinkTalk.NET(909327571)<br>严格遵守actor模式可以有效的避免死?<br><br>2009-12-7 23:13:04 david(258667581)<br>[表情]<br><br>2009-12-7 23:14:34 LinkTalk.NET(909327571)<br>我也在摸索和试Qerlang的消息调度和分布式支持是目前最好的<br><br>2009-12-7 23:14:49 LinkTalk.NET(909327571)<br>scala也不错,twitter放弃erlang转向scala<br><br>2009-12-7 23:15:00 LinkTalk.NET(909327571)<br>但是scala在分布式支持斚w不及erlang<br><br>2009-12-7 23:15:30 LinkTalk.NET(909327571)<br>但是scala有最大的好处是ZJVMQ可以利用java的各U好?br><br>2009-12-7 23:15:33 david(258667581)<br>分布式以后是势 所以感觉erlang的生命力应该q是很强?br><br>2009-12-7 23:15:44 LinkTalk.NET(909327571)<br>嗯,分布式其实其他语a也可以做?br><br>2009-12-7 23:16:05 LinkTalk.NET(909327571)<br>只是erlang已经做了十几q了<br><br>2009-12-7 23:16:19 LinkTalk.NET(909327571)<br>其他语言也肯定会逐渐支持?br><br>2009-12-7 23:16:25 david(258667581)<br>?br><br>2009-12-7 23:16:43 LinkTalk.NET(909327571)<br>但是我个人比较觉得遗憄是erlang的语法和~程模式<br><br>2009-12-7 23:17:08 LinkTalk.NET(909327571)<br>如果erlang代码上到一定的量以后维护和调试q当麻烦了<br><br>2009-12-7 23:17:11 david(258667581)<br>语法习惯了就?关键是对于结构的支持<br><br>2009-12-7 23:17:17 david(258667581)<br>可读性太?br><br>2009-12-7 23:17:31 LinkTalk.NET(909327571)<br>嗯,数据l构表现力也不够丰富<br><br>2009-12-7 23:17:35 LinkTalk.NET(909327571)<br>都是tuple<br><br>2009-12-7 23:17:43 LinkTalk.NET(909327571)<br>眼睛要看׃<br><br>2009-12-7 23:19:09 david(258667581)<br>开发环境也没跟?没有很好的IDE<br><br>2009-12-7 23:19:16 LinkTalk.NET(909327571)<br>?br><br>2009-12-7 23:19:37 LinkTalk.NET(909327571)<br>脚本语言重构hq当麻烦了<br><br>2009-12-7 23:19:57 T.t.T!Ck.K?(121787333)<br>有一个老外也用C#来模拟erlang的模?br><br>2009-12-7 23:20:06 LinkTalk.NET(909327571)<br>因ؓ无类型,无法反射元数据,没有办法自动生成文档Q更N?br><br>2009-12-7 23:20:07 Lenn(28663)<br>ERLANG跟Java一h~译态语aQ怎么成脚本语a?br><br>2009-12-7 23:20:22 LinkTalk.NET(909327571)<br>erlang严格来讲是脚?br><br>2009-12-7 23:20:31 LinkTalk.NET(909327571)<br>q型的基本都是脚本<br><br>2009-12-7 23:20:44 LinkTalk.NET(909327571)<br>包括php也号U支持编?br><br>2009-12-7 23:20:47 LinkTalk.NET(909327571)<br>其实q是脚本<br><br>2009-12-7 23:21:16 Lenn(28663)<br>bin code只有200多条指oQ属于典型的中间太语aQ效率不会比Java差多?br><br>2009-12-7 23:21:34 LinkTalk.NET(909327571)<br>?br><br>2009-12-7 23:21:48 LinkTalk.NET(909327571)<br>我觉得Q何东襉K有得必有?br><br>2009-12-7 23:21:57 LinkTalk.NET(909327571)<br>一斚w太强了,比如有其他的~陷<br><br>2009-12-7 23:22:06 LinkTalk.NET(909327571)<br>q自己的喜好和具体的应用场景了<br><br>2009-12-7 23:22:08 Lenn(28663)<br>囑Ş太弱<br><br>2009-12-7 23:22:47 Lenn(28663)<br>调试h最爽,业务惛_了基本不会编E从出错<br><br>2009-12-7 23:23:16 LinkTalk.NET(909327571)<br>?br><br>2009-12-7 23:24:26 Lenn(28663)<br>我们是一个案例,用JQ)Q做的东西,现在q不停改代码QIrlang那一块,要改也只是几行一会的事情<br><br>2009-12-7 23:25:17 jack(357794482)<br>其实q种事情要看你对语言的处理能?<br><br>2009-12-7 23:25:20 LinkTalk.NET(909327571)<br>?br><br>2009-12-7 23:25:35 LinkTalk.NET(909327571)<br>google的首席架构师是搞java?br><br>2009-12-7 23:25:41 LinkTalk.NET(909327571)<br>其实q个看具体情늚<br><br>2009-12-7 23:26:17 Lenn(28663)<br>用什么还有历史原因,比如新的facebook很多用Erlang<br><br>2009-12-7 23:26:33 Lenn(28663)<br>因ؓ做好的东西更改语a是个大问?br><br>2009-12-7 23:26:36 LinkTalk.NET(909327571)<br>但是更新的twitter由erlang转向了scala<br><br>2009-12-7 23:26:58 LinkTalk.NET(909327571)<br>另外erlang十几q了Q到今天才红Q也是有一定的原因?br><br>2009-12-7 23:27:13 LinkTalk.NET(909327571)<br>erlang有非常突出的优势Q但是也存在一些不够完的地方<br><br>2009-12-7 23:29:04 Lenn(28663)<br>现在C֌也挺z跃Q业务有比较强的优势<br><br>2009-12-7 23:29:37 LinkTalk.NET(909327571)<br>嗯,是的Q)<br><br>2009-12-7 23:29:57 LinkTalk.NET(909327571)<br>所以就其他语a的开发h员也开始了?br><br>2009-12-7 23:30:02 LinkTalk.NET(909327571)<br>学习?br><br>2009-12-7 23:30:04 Lenn(28663)<br>囑Ş斚w却丝毫不?br><br>2009-12-7 23:30:05 LinkTalk.NET(909327571)<br>或模拟erlang<br><br>2009-12-7 23:30:08 LinkTalk.NET(909327571)<br>?br><img src ="http://www.shnenglu.com/keigoliye/aggbug/102764.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/keigoliye/" target="_blank">暗夜教父</a> 2009-12-07 23:49 <a href="http://www.shnenglu.com/keigoliye/archive/2009/12/07/102764.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Patch Mnesia 使用TokyoCabinet引擎H破2G存储限制http://www.shnenglu.com/keigoliye/archive/2009/09/29/97547.html暗夜教父暗夜教父Tue, 29 Sep 2009 07:12:00 GMThttp://www.shnenglu.com/keigoliye/archive/2009/09/29/97547.htmlhttp://www.shnenglu.com/keigoliye/comments/97547.htmlhttp://www.shnenglu.com/keigoliye/archive/2009/09/29/97547.html#Feedback0http://www.shnenglu.com/keigoliye/comments/commentRss/97547.htmlhttp://www.shnenglu.com/keigoliye/services/trackbacks/97547.html为啥要PATCHQ?/p>

    Mnesia最大的~陷是存储限制。这不是数据库系l的错误Q因为Mnesia能够控制虚拟数据的大。主要的问题在于q时的Erlang DETS存储引擎Q速度慢ƈ且用的32位偏U量Q限制单文g大小?GBQ?

思\Q?/p>

    乎惌?mnesia 补丁?mnesiaex 。这个东西解除了加在 mnesia 数据库系l上所有的限制(虽说上面已经提到Q实际上 mnesia 代码本n没有什么真正的限制)——你现在可以?SleepyCat/BerkeleyDB/MySQL/Amazon S3/Tokyo Cabinet/… 甚至是你自己喜欢的某U东西来当作 mnesia 的后端,像 ets/dets 一栗而访问的接口仍保持不变——l沿?mnesia 的接口,一行也不用攏V?DIY q种扩展也变得相当容易,写一?behavior 成了?/p>

实现q程

1Q与从源代码~译的方式安装Erlang

tar xvf otp_src_R12B-5.tar.gz

cd otp_src_R12B-5

./configure & make & make install

注意Q我的系l是RHEL 5.3Q默认安装目录ؓ/usr/local/erlang

2Q安装Mnesiaex

tar xvf mnesia-4.4.7.6.tar.gz

cd mnesia-4.4.7.6

./configure --prefix=/usr/local

make

make check

make install

注意Q这里一定要指定prefixQ不然就装到/usr目录M

3Q安装Tokyo Cabinet

tar xvf  tokyocabinet-1.4.10.tar.gz

cd tokyocabinet-1.4.10

./configure --prefix=/usr

make & make install

3Q安装tcerl

tar xvf tcerldrv-1.3.1e.tar.gz

cd tcerldrv-1.3.1e

./configure --prefix=/usr

make & make install

tar xvf tcerl-1.3.1e.tar.gz

cd tcerl-1.3.1e

./configure --prefix=/usr/local

make & make install

 

本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/jimmychou/archive/2009/03/13/3988468.aspx



暗夜教父 2009-09-29 15:12 发表评论
]]>
关于Erlang和SMP的一些说?/title><link>http://www.shnenglu.com/keigoliye/archive/2009/09/24/97172.html</link><dc:creator>暗夜教父</dc:creator><author>暗夜教父</author><pubDate>Thu, 24 Sep 2009 14:23:00 GMT</pubDate><guid>http://www.shnenglu.com/keigoliye/archive/2009/09/24/97172.html</guid><wfw:comment>http://www.shnenglu.com/keigoliye/comments/97172.html</wfw:comment><comments>http://www.shnenglu.com/keigoliye/archive/2009/09/24/97172.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/keigoliye/comments/commentRss/97172.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/keigoliye/services/trackbacks/97172.html</trackback:ping><description><![CDATA[<div id="iagiasc" class=entry-content> <p><a ><u><font color=#0000ff>http://shiningray.cn/some-facts-about-<span id="wsyuykk" class=hilite1>erlang</span>-and-smp.html</font></u></a></p> <p>原文Q?a ><u><font color=#0000ff>http://groups.google.com/group/<span id="yoeosqs" class=hilite1>erlang</span>-questions/browse_thread/thread/7827f5e32681ca8e</font></u></a> </p> <p>by.Kenneth <span id="sugamui" class=hilite1>Erlang</span>/OTP team, Ericsson<br>译:<a ><u><font color=#0000ff>ShiningRay <br></font></u></a></p> <p> </p> <p>以下是一?span class=hilite1>Erlang</span> SMP实现的细节和与性能与׾~性相关一些简单介l?/p> <p>几周之内q有有一个关于多核如何运作以及未来如何发展的更详l的介绍。我打算一些内Ҏ在我的报告中Q将??7日的ICFP2008Q?span class=hilite1>Erlang</span> Workshop在Victoria BC展示l大家?/p> <p>没有SMP支持?span class=hilite1>Erlang</span> VM只有1个运行在d理线E中的调度器。该调度器从q行队列Qrun-queueQ中取出可以q行?span class=hilite1>Erlang</span>q程以及IOdQ而且因ؓ只有一个线E访问他们所以无锁定Q何数据?/p> <p>而带有SMP支持?span class=hilite1>Erlang</span> VM可以有一个或多个调度器,每个q行在一个线E中。调度器从同一个公p行队列中取出可运行的<span id="kwqceec" class=hilite1>Erlang</span>q程和IOd。在SMP VM中所有的׃n数据l构都会由锁q行保护Q运行队列就是这样一个由锁保护的数据l构?/p> <p>从OTP R12B开始,如果操作pȝ报告有多?个的CPUQ或者核心)VM的SMP版本会自动启动,q且ҎCPU或者核心的数量启动同样数量的调度器?/p> <p>你可以从“erl”命o打印出来的第一行看到它选择了哪些参数。例如:</p> <pre><code> <span id="gimgwwy" class=hilite1>Erlang</span> (BEAM) emulator version 5.6.4 [source] [smp:4] [asynch-threads:0] ….. 其中“[smp:4]”表示SMP VMq行?个调度器?/code> </pre> <p>默认值可以用“-smp [enable|disable|auto]”来替换,auto是默认的。如果smp被启用了Q?smp enableQ,要设|调度器的数量可以?#8220;+S Number”其中Number是调度器的数量(1?024Q?/p> <p>注意1Q运行多于CPU或核心L的调度器不会有Q何提升?/p> <p>注意2Q在某些操作pȝ中一个进E可使用的CPU或者核心的数量可以被限制。例如,在Linux中,命o“taskset”可以实现这个功能?<span id="yicwskq" class=hilite1>Erlang</span> VM目前q只能探CPU或者核心的LQ不会考虑“taskset”所讄的掩码。正因如此,例如可能会出玎ͼ已经出现q了Q即?span class=hilite1>Erlang</span> VMq行?个调度器Q也只用了2个核心。OS会进行限制因为它要考虑“taskset”所讄的掩码?/p> <p>每个<span id="mimwiwu" class=hilite1>Erlang</span> VM的调度器都运行于一个OSU程上,是OS来决定线E是否执行在不同的核心上。一般来说OS会很好地处理q个问题q且会保证线E在执行期间q行于同一个核心上?/p> <p><span id="kgkcgwk" class=hilite1>Erlang</span>q程会被不同的调度器q行Q因Z们是从一个公p行队列中被取出,由首先可用的调度器运行?/p> <h3>性能和׾~?/h3> <p>只有一个调度器的SMP VM要比非SMP的VME微慢那么一点点。SMP VM内部需要用到各U锁Q不q只要不存在锁的争用Q那么由锁引L开销不会非常大(是锁争用上面需要花旉Q。这也解释了Z在某些情况下Q运行多个只有一个调度器的SMP VM要比包含多个调度器的单一SMP VM更加高效。当然运行多个VM要求应用可以按照多个q行d的方式运行ƈ且之间没有或者几乎不通讯?/p> <p>一个程序是否能在多怸的SMP VM中良好地q行提升很大E度上取决于E序的性质Q某些程序可以保持线性提升至8核甚?6核,同时其他某些E序基本不能提升Q连2栔R不行。实际应用中很多E序都能在主市场的核心C得到提升Q见下文?/p> <p>若ƈ行的持箋“通话”由每个核心一个或多个<span id="wamwiia" class=hilite1>Erlang</span>q程来表C,实际的支持大量通话的电信品已l先现出在双核和四核处理器上不俗的׾~性。注意,q些产品是在SMP VM和多核处理器出现很久以前按照普通的<span id="kyskgwa" class=hilite1>Erlang</span>风格来写的,他们也能无须M修改甚至不需重新~译代码p?span class=hilite1>Erlang</span> SMP VM中获益?/p> <h3>SMP性能得到持箋改进</h3> <p>SMP实现正被不断改进以便能得到更好的性能和׾~性。在每个服务发布版R12B-1,2,3,4,5…,R13B{等中,你都能发现新的优化?/p> <h3>一些已知的瓉</h3> <p>单一的常见运行队列随着CPU或核心的数量的增加会成ؓ一个显著的瓉?/p> <p>q从4核开始往上就会显现出来,不过4总然可以ؓ多数应用E序提供不错的性能。我们正在从事一个每个调度器一个运行队列的解决Ҏ作ؓ目前最重要的改q?/p> <p>Ets表格会引入锁。在R12B-4之前在每ơ对一个ets-table的访问中会用C个锁Q但是在R12B-4中meta-table的锁被优化过Q可以显著减争用(前面已经提到争用是有很大代h的)。如果很?span class=hilite1>Erlang</span>q程讉K同一个表|׃有很多锁争用造成性能降低其当这些进E主要工作是讉Kets-table。锁存在于表U而非记录U。注意!q也会媄响到Mnesia因ؓMnesia用到了很多ets-table?/p> <h3>我们关于SMP的策?/h3> <p>当我们开始实现SMP VM的最初,我们q定了{略Q?#8220;首先让它可以q行Q然后测量,然后优化”。自?006q五月我们发布了W一个稳定的SMP VMQR11BQ以来,我们一直遵循着q个{略?/p> <p>q有更多已知的东西可以改q,我们会按照性能的收益大先后各个击破?/p> <p>我们主要的_֊攑֜多核Q大?Q上更好的连l׾~性上?/p> <h3>卓越典范</h3> <p>即SMPpȝ有还有一些已知的瓉不过已经有不错的整体性能和׾~性,同时我相信在让程序员利用多核机器事半功倍方面,我们是一个卓的典范?/p> </div> <img src ="http://www.shnenglu.com/keigoliye/aggbug/97172.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/keigoliye/" target="_blank">暗夜教父</a> 2009-09-24 22:23 <a href="http://www.shnenglu.com/keigoliye/archive/2009/09/24/97172.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Erlang开发徏?杂记?http://www.shnenglu.com/keigoliye/archive/2009/09/24/97082.html暗夜教父暗夜教父Wed, 23 Sep 2009 17:00:00 GMThttp://www.shnenglu.com/keigoliye/archive/2009/09/24/97082.htmlhttp://www.shnenglu.com/keigoliye/comments/97082.htmlhttp://www.shnenglu.com/keigoliye/archive/2009/09/24/97082.html#Feedback0http://www.shnenglu.com/keigoliye/comments/commentRss/97082.htmlhttp://www.shnenglu.com/keigoliye/services/trackbacks/97082.htmlerlang目开发中的一些记录,卛_含很多通俗易懂的原则,也包含一些似是而非的徏议,比较混ؕQ还没有U篏C个可以分门别cȝ地步Q各位就就看吧..
:)

* 保没有M~译警告

* Erlang中String采用list实现Q?2位系l中Q其1个字W用8个字节的I间Q?个保存value, 4个保存指?。因此string速度较慢Q空间占用较?

* 在Server中,L力书写N归(tail-recursive)的函?

* 使用'++'Ӟleft list会被拯Q然后添加到right list的头部,因此最好把length较短的list攑֜左侧

* 避免使用regexpQ如果需要正则表辑ּQ请使用re

* timer模块的大部分函数实现Q依赖于一个processQ如果过多用timerQ会Dq个process负蝲q大Q媄响效率?
  推荐使用erlang:send_after/3?span class="hilite1">erlang:start_timer/3

* 避免使用list_to_atom/1Q因?span class="hilite1">erlang中atom数量最大ؓ1048576, 且不q行GC控制。因此如果持l性的调用list_to_atom/1
  可能很容易达到系l上限,从而导致emulator terminate。请使用list_to_existing_atom/1?

* list内部实现Z个列表,因此length(List), 需要遍历整个list比较耗时

* 对于不同的数据类型,使用不同的size函数Qtuple_size/1, byte_size/1, bit_size/1

* 使用binary match来进行binary的分Ԍ而不使用split_binary/2

* 如果两个list都拥有很多数据,那么请不要?--'Q而是数据{化到ordsetsQ然后调用ordsets:substract/2.

* 对于binary相关操作可以q行binary优化Qbin_opt_info~译选项Q代码框Ӟ

*   f(<<Pattern1,...,Rest/bits>>,...) -> 
       ... % Rest is not used here 
       f(Rest,...); 
    f(<<Pattern2,...,Rest/bits>>,...) -> 
      ... % Rest is not used here 
      f(Rest,...); 
    ... 
    f(<<>>, ...) -> 
      ReturnValue.

* 调用lists:flatten/1可以list扁^化,q个操作代h很大Q比'++'q要昂贵。下面这些时候我们可以避免:
    数据发送给port?
    调用list_bo_binary/1和iolist_to_binary?

* 的函数可以让您方便的找出错误的函数和代?

* 不要在同一行出现相同的W号
20    some_fun() ->
21       L = [{key1, v1}, {key2, [some_record#v21, v22]}],
22      ...
~译Ӟ会提Cline 21 '[' 语法错误Q? 因ؓ21行有多个 '[' Q所以这个bug不能准确定位Q你需要花旉L查代码?
好的做法是:
20 some_fun() ->
21      L = [{key1, v1},
22            {key2, [some_record#v21, v22]}
23            ],
      ...
q样Q编译其会提CZ line 22 '[' 语法错误Q你很开q道是那个地方错了?

* 使用 CTRL Q?\ ?init:stop()Q?可以退?span class="hilite1">ErlangQ?使用CTRL Q?G ?CTRL + C 弹出菜单选项Q可以选择是否退?span class="hilite1">Erlang?
其中CTRL Q?G可以用来q接其他的shellQ?CTRL Q?C可以查看其他一些系l信?
Ctrl + C abort 是野蛮的退出方?

* use "open_port({fd,0,2}, [out])" make erlang program write standard error to unix system

* If you don't run experiments before you start designing a new system, your entire system will be an experiment!

* standard data structure desc:

Module Description
sets sets, i.e. a collection of unique elements.
gb_sets sets, but based on a general balanced data structure
gb_tree a general balanced tree
dict maps, also called associative arrays
ets hash tables and ordered sets (trees)
dets on-disk hash tables

SuggestionQ?
elments count: 0 Q?100 | 100 - 10000  |  10000 -
our select   :  list   |      ets     |  gb_tree

* 通过code:clash/0 代码中是否有module冲突现象Qsticky)

* epmd -d -d 启动 epmd 可以查看erlang node之间的通讯

* 正常的逻辑代码和错误处理代码分,发生错误Ӟ管错误。由另一个错误处理模块进行处?

* cM于操作系l,我们的程序也可以分ؓkernel ? user 两层Q?对于kernell对不能出现错误Q?对于user可以出现错误Q进行恢?

* process层loop涉及的代码及函数Q最好在一个module中实?

* process 的register name和module名称一_ 便于L代码

* 每个processh一个单一的角Ԍ比如Qsupervisor 用来q行错误恢复Q? work 工作者,可以出现错误Q?trusted worker 不会出现错误

* 通过函数调用可以实现的功能,׃要用sever实现Q如gen_server, 及类似的loop 实现Q?

* l消息加一个tagQ在发生错误的时候,可以定位到消息,同时也有利于E序的稳?

* 在消息@环中Q对于unknown的消息,误用lib:flush_receive/0 其清除Q减轻process msg queue的长?

* server中L书写N归的@?

* 量使用recordQ?而不是原始的tuple来表现数据结构, 在用recordӞ使用select matchQ?
#person{name = Name, age = Age} = Person

* 对于q回|最好也d一个tagQ用来说明返回值类型,或者执行成功与?

* 可能少的用catch和tryQ在erlangE序中,不推荐主动捕获异常。只有当我们的逻辑特别复杂Q我们可以用throw来返回数据,使用catch来获取返回倹{?

* 当然E序与外界交互,外界数据不可靠时Q需要用catch和try

* 慎重使用process dictoryQ? 当你使用get/1, put/1Ӟ你的应用会具有很大的slide effect。可以通过加入一个新的参数来保存原本需要存储到process dictory中数?

* 如果不想使自q涂,请不要用import

* 使用exportӞ功能类似的接口l合在一Pq添加合理的注视Q这样你的接口更清晰Q别Z用v来更方便

* 不要书写嵌套太深的代?

* 不要书写太长的module

* 不要书写太长的函?

* 每行代码不能太长

* 避免使用 "_" 匿名变量Q请为每个变量选择有意义的名称Q如够某个变量暂时不使用Q请以下划线 "_" 开?

* {error, enfile} enfile error in socket 是以为内linuxpȝ?ulimit 限制Q?在root下修改:ulimit -n 25000

* {error, enotconn} 表示socket已经关闭

* ?span class="hilite1">erlang开发时Q慎重用macroQ因?span class="hilite1">erlang的single assign的缘故,同时调用某个marcoQ而macro又定义了某个变量Q可能导致badmatch错误?
比如Q?
-define(ADDLINEINFO1(F),
        (
        begin
        Str1 = lists:concat(["[Mod:", ?MODULE, " Line:", ?LINE, "]"]),
        Str1 ++ F
        end
        )).
-define(WARN(Log, F, D), log4erl:warn(Log, ?ADDLINEINFO(F), D)).
如果q箋使用 WARN, 会出现此错误

* erlang中可以定义很多环境变量:
ERL_MAX_ETS_TABLES 讄最大的ets数目 默认1400
ERL_MAX_PORTS erlang最大的port数目 默认1024

* .app文g中的start_phasesQ?选项既可以用来作为include applications之间的同步启动,也可以用来对单个applicationq行分布启动?
序如下
包含included app:

application:start(prim_app)
=> prim_app_cb:start(normal, [])
=> prim_app_cb:start_phase(init, normal, [])
=> prim_app_cb:start_phase(go, normal, [])
=> incl_app_cb:start_phase(go, normal, [])
ok

无included app:
application:start(prim_app)
=> prim_app_cb:start(normal, [])
=> prim_app_cb:start_phase(init, normal, [])
=> prim_app_cb:start_phase(go, normal, [])
ok

* M时候,都要重视函数的返回|通过match保您的预期Q如果发生错误,那么大胆的表达出来?

暗夜教父 2009-09-24 01:00 发表评论
]]>
在MacOSX上测试Mochiweb遇到的一些问?/title><link>http://www.shnenglu.com/keigoliye/archive/2009/09/24/97081.html</link><dc:creator>暗夜教父</dc:creator><author>暗夜教父</author><pubDate>Wed, 23 Sep 2009 16:59:00 GMT</pubDate><guid>http://www.shnenglu.com/keigoliye/archive/2009/09/24/97081.html</guid><wfw:comment>http://www.shnenglu.com/keigoliye/comments/97081.html</wfw:comment><comments>http://www.shnenglu.com/keigoliye/archive/2009/09/24/97081.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/keigoliye/comments/commentRss/97081.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/keigoliye/services/trackbacks/97081.html</trackback:ping><description><![CDATA[<a target="_blank">A Million-user Comet Application with Mochiweb, Part 1</a> <br>在MacOSXq_上遇到的一些问题: <br><br>一. IPv6D的问? <br>在MacOS下测试时报错econnrefusedQmochi-urls.txt文g的url不能用localhostQ得?27.0.0.1才行 <br><br>在Erlang的邮件列表中扑ֈ了解释: <br>We have seen the same issue with CouchDB. What we found out <br>is that in our case localhost was not only resolving to 127.0.0.1 (IPv4) <br>but also ::1 (IPv6) and that http:request() would try to connect to <br>::1 where no service was listening. <br><br>Erlang的http模块~省是打开IPv6模式的,当测试程序通过http模块q接localhostӞq接的地址是IPv6?:1地址Q但是mochi没有在此监听Q所以连接出? {error,econnrefused} <br><br>解决Ҏ两种Q?<br>1. mochi-urls.txt中的地址都改?27.0.0.1 <br>2. 在http:request(…)q行之前调用http:set_options([{ipv6,disabled}])Q关闭测试程序的IPv6模式Q用IPv4模式 <br><br>理论上还有一U方法:让mochi服务器开启IPv6模式监听Q这个我不知道这么开Q?<br>参?<br>You should teach Yaws to listen also on IPv6 - “localhost” resolves not <br>only to IPv4 127.0.0.1, but also to IPv6 ::1. <br><br><br>? q程能打开的文件描q符数量的限? <br>MacOSX下缺省能同时打开的文件描q符最大数?56个,使用 ulimit -a命o查看 <br>$ ulimit -a <br>core file size          (blocks, -c) 0 <br>data seg size           (kbytes, -d) 6144 <br>file size               (blocks, -f) unlimited <br>max locked memory       (kbytes, -l) unlimited <br>max memory size         (kbytes, -m) unlimited <br><strong>open files                      (-n) 256 <br></strong>pipe size            (512 bytes, -p) 1 <br>stack size              (kbytes, -s) 8192 <br>cpu time               (seconds, -t) unlimited <br>max user processes              (-u) 266 <br>virtual memory          (kbytes, -v) unlimited <br>使用ulimit -n XXXX讄Q但最大数量还是不能超q?0240 <br><br>查看内核每进E最大文件数Q?<br>$ sysctl kern.maxfiles kern.maxfilesperproc <br>kern.maxfiles: 12288 <br>kern.maxfilesperproc: 10240 <br><br>增大每进E最大文件数Q?<br>$ sudo sysctl -w kern.maxfilesperproc=20480 kern.maxfiles=22528 <br><br>然后讄 <br>$ ulimit -n 20480 <br>注意ulimit只在每个shellH口生命周期内有效,当新开一个shell后,得再ơ设|?<br>sysctl做的修改没有q个问题 <br><br>三、调节IP端口可_不然最多只能有15K个连?<br>~省动态端口号?9152开始,Ҏ2000后最多可以有63K个连? <br>sysctl -w net.inet.ip.portrange.hifirst=2000 net.inet.ip.portrange.first=2000 <br><img src ="http://www.shnenglu.com/keigoliye/aggbug/97081.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/keigoliye/" target="_blank">暗夜教父</a> 2009-09-24 00:59 <a href="http://www.shnenglu.com/keigoliye/archive/2009/09/24/97081.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ubuntu下编译安装Erlanghttp://www.shnenglu.com/keigoliye/archive/2009/09/18/96660.html暗夜教父暗夜教父Fri, 18 Sep 2009 11:12:00 GMThttp://www.shnenglu.com/keigoliye/archive/2009/09/18/96660.htmlhttp://www.shnenglu.com/keigoliye/comments/96660.htmlhttp://www.shnenglu.com/keigoliye/archive/2009/09/18/96660.html#Feedback0http://www.shnenglu.com/keigoliye/comments/commentRss/96660.htmlhttp://www.shnenglu.com/keigoliye/services/trackbacks/96660.html先要q样
apt-get install build-essential  
apt-get install libncurses5-dev  
apt-get install m4  
apt-get install libssl-dev 


然后要用新立得装如下库:
libc6
unixodbc
unixodbc-dev
gcj

freeglut3-dev
libwxgtk2.8-dev
g++


然后下蝲源代?
tar -xvf otp-src-R12B-0.tar.gz  
cd otp-src-R12B-0 
sudo ./configure --prefix=/otp/erlang  
sudo make  
sudo make install 


安装完毕Q可以rm -fr opt-src-R12B-0删除源代?

然后Ҏ/etc/profile
export PATH=/opt/erlang/bin:$PATH
alias ls='ls -color=auto'
alias ll='ll -lht'

可以source /etc/profile一下,及时修改PATH



暗夜教父 2009-09-18 19:12 发表评论
]]>
Erlang与ActionScript3采用JSON格式q行Socket通讯http://www.shnenglu.com/keigoliye/archive/2009/09/18/96649.html暗夜教父暗夜教父Fri, 18 Sep 2009 08:07:00 GMThttp://www.shnenglu.com/keigoliye/archive/2009/09/18/96649.htmlhttp://www.shnenglu.com/keigoliye/comments/96649.htmlhttp://www.shnenglu.com/keigoliye/archive/2009/09/18/96649.html#Feedback0http://www.shnenglu.com/keigoliye/comments/commentRss/96649.htmlhttp://www.shnenglu.com/keigoliye/services/trackbacks/96649.html需要下?a target=_blank>as3corelib来ؓActionScript3处理JSON codec

server.erl
-module(server).   
-export([start/0,start/1,process/1]).   
-define(defPort, 8888).   
  
start() 
-> start(?defPort).   
  
start(Port) 
->   
  
case gen_tcp:listen(Port, [binary, {packet, 0}, {active, false}]) of   
    {ok, LSock} 
-> server_loop(LSock);   
    {error, Reason} 
-> exit({Port,Reason})   
  end.   
  
%% main server loop - wait for next connection, spawn child to process it   
server_loop(LSock) 
->   
  
case gen_tcp:accept(LSock) of   
    {ok, Sock} 
->   
      spawn(
?MODULE,process,[Sock]),   
      server_loop(LSock);   
    {error, Reason} 
->   
      exit({accept,Reason})   
  end.   
  
%% process current connection   
process(Sock) 
->   
  Req 
= do_recv(Sock),   
  io:format(
"~p~n", [Req]),   
  {ok, D, []} 
= rfc4627:decode(Req),   
  {obj, [{
"name", _Name}, {"age", Age}]} = D,   
  Name 
= binary_to_list(_Name),   
  io:format(
"Name: ~p, Age: ~p~n", [Name, Age]),   
  Resp 
= rfc4627:encode({obj, [{"name"'Hideto2'}, {"age"24}]}),   
  do_send(Sock,Resp),   
  gen_tcp:close(Sock).   
  
%% send a line of text to the socket   
do_send(Sock,Msg) 
->   
  
case gen_tcp:send(Sock, Msg) of   
    ok 
-> ok;   
    {error, Reason} 
-> exit(Reason)   
  end.   
  
%% receive data from the socket   
do_recv(Sock) 
->   
  
case gen_tcp:recv(Sock, 0) of   
    {ok, Bin} 
-> binary_to_list(Bin);   
    {error, closed} 
-> exit(closed);   
    {error, Reason} 
-> exit(Reason)   
  end.  

Person.as
package  
{   
    
public class Person   
    {   
        
public var name:String;   
        
public var age:int;   
        
public function Person()   
        {   
        }   
    }   
}  

Client.as
package {   
    
import com.adobe.serialization.json.JSON;   
       
    
import flash.display.Sprite;   
    
import flash.events.*;   
    
import flash.net.Socket;   
    
import flash.text.*;   
       
    
public class Client extends Sprite   
    {   
        
private var socket:Socket;   
        
private var myField:TextField;   
        
private var send_data:Person;   
        
public function Client()   
        {   
            socket 
= new Socket();   
            myField 
= new TextField();   
            send_data 
= new Person();   
            send_data.name 
= "Hideto";   
            send_data.age 
= 23;   
            socket.addEventListener(ProgressEvent.SOCKET_DATA, onSocketData);   
            socket.connect(
"localhost"8888);   
            socket.writeUTFBytes(JSON.encode(send_data));   
            socket.flush();   
            myField.x 
= 20;   
            myField.y 
= 30;   
            myField.text 
= "test";   
            myField.autoSize 
= TextFieldAutoSize.LEFT;   
            addChild(myField);   
        }   
        
private function onSocketData(event:ProgressEvent):void {   
            
while(socket.bytesAvailable) {   
                var recv_data:
* = JSON.decode(socket.readUTFBytes(socket.bytesAvailable));   
                myField.text 
= "Name: " + recv_data.name + ", age: " + recv_data.age.toString();   
            }   
        }   
    }   

q行Erlang服务器端Q?br>
Eshell> c(server).   
Eshell
> server:start().   
"{\"name\":\"Hideto\",\"age\":23}"  
Name: 
"Hideto", Age: 23 

q里打印ZErlang Socket Server接收到的AS3 Client发过来的JSON decodeq的一个person对象

q行AS3客户端:
client.html上首先显C?#8220;test”Q然后异步处理完Socket消息发送和接受后,decode Erlang Server端发q来的person对象Q将面上的TextField替换?#8220;Name: Hideto2, age: 24”

暗夜教父 2009-09-18 16:07 发表评论
]]>
Erlang的JSON?/title><link>http://www.shnenglu.com/keigoliye/archive/2009/09/18/96647.html</link><dc:creator>暗夜教父</dc:creator><author>暗夜教父</author><pubDate>Fri, 18 Sep 2009 07:38:00 GMT</pubDate><guid>http://www.shnenglu.com/keigoliye/archive/2009/09/18/96647.html</guid><wfw:comment>http://www.shnenglu.com/keigoliye/comments/96647.html</wfw:comment><comments>http://www.shnenglu.com/keigoliye/archive/2009/09/18/96647.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/keigoliye/comments/commentRss/96647.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/keigoliye/services/trackbacks/96647.html</trackback:ping><description><![CDATA[使用下列JSON库: <br><a target=_blank><u><font color=#810081>http://www.lshift.net/blog/2007/02/17/json-and-json-rpc-for-erlang</font></u></a> <br><br>该JSON库采?a target=_blank><u><font color=#0000ff>Joe Armstrong prefered Data type mapping</font></u></a> <br>卻I <br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id=Codehighlighter1_29_51_Open_Image onclick="this.style.display='none'; Codehighlighter1_29_51_Open_Text.style.display='none'; Codehighlighter1_29_51_Closed_Image.style.display='inline'; Codehighlighter1_29_51_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_29_51_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_29_51_Closed_Text.style.display='none'; Codehighlighter1_29_51_Open_Image.style.display='inline'; Codehighlighter1_29_51_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedBlock.gif" align=top><span style="COLOR: #000000">JSON Obj    </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> type obj()   </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span id=Codehighlighter1_29_51_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_29_51_Open_Text><span style="COLOR: #000000">{obj, [</span><span id=Codehighlighter1_36_49_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_36_49_Open_Text><span style="COLOR: #000000">{key(), val()}</span></span><span style="COLOR: #000000">]}</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>JSON Array  </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> type array() </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> [val()]   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>JSON Number </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> type num()   </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">() </span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">()    <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>JSON String </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> type str()   </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> bin()   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>JSON </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">       </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">, </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000"> (atoms)   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>With Type val() </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> obj() </span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"> array() </span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"> num() </span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"> str() </span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">  <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>and key() being a str(). (Or a binary or atom, during JSON encoding.)  </span></div> <br>试如下Q?<br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">Eshell V5.</span><span style="COLOR: #000000">6.3</span><span style="COLOR: #000000">  (abort with </span><span style="COLOR: #000000">^</span><span style="COLOR: #000000">G)   <br><img id=Codehighlighter1_56_89_Open_Image onclick="this.style.display='none'; Codehighlighter1_56_89_Open_Text.style.display='none'; Codehighlighter1_56_89_Closed_Image.style.display='inline'; Codehighlighter1_56_89_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_56_89_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_56_89_Closed_Text.style.display='none'; Codehighlighter1_56_89_Open_Image.style.display='inline'; Codehighlighter1_56_89_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> O </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> rfc4627:encode(</span><span id=Codehighlighter1_56_89_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_56_89_Open_Text><span style="COLOR: #000000">{obj, [</span><span id=Codehighlighter1_63_76_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_63_76_Open_Text><span style="COLOR: #000000">{name, hideto}</span></span><span style="COLOR: #000000">, </span><span id=Codehighlighter1_79_87_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_79_87_Open_Text><span style="COLOR: #000000">{age, </span><span style="COLOR: #000000">23</span><span style="COLOR: #000000">}</span></span><span style="COLOR: #000000">]}</span></span><span style="COLOR: #000000">).   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">{\</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">name\</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">:\</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">hideto\</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,\</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">age\</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">:23}</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">  <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> rfc4627:decode(O).   <br><img id=Codehighlighter1_164_211_Open_Image onclick="this.style.display='none'; Codehighlighter1_164_211_Open_Text.style.display='none'; Codehighlighter1_164_211_Closed_Image.style.display='inline'; Codehighlighter1_164_211_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_164_211_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_164_211_Closed_Text.style.display='none'; Codehighlighter1_164_211_Open_Image.style.display='inline'; Codehighlighter1_164_211_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_164_211_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_164_211_Open_Text><span style="COLOR: #000000">{ok,</span><span id=Codehighlighter1_168_207_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_168_207_Open_Text><span style="COLOR: #000000">{obj,[</span><span id=Codehighlighter1_174_194_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_174_194_Open_Text><span style="COLOR: #000000">{</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">name</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000"><<</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">hideto</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">>></span><span style="COLOR: #000000">}</span></span><span style="COLOR: #000000">,</span><span id=Codehighlighter1_196_205_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_196_205_Open_Text><span style="COLOR: #000000">{</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">age</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">23</span><span style="COLOR: #000000">}</span></span><span style="COLOR: #000000">]}</span></span><span style="COLOR: #000000">,[]}</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> A </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> rfc4627:encode([</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">]).   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">[1,2,3,4,5]</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">  <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> rfc4627:decode(A).   <br><img id=Codehighlighter1_296_314_Open_Image onclick="this.style.display='none'; Codehighlighter1_296_314_Open_Text.style.display='none'; Codehighlighter1_296_314_Closed_Image.style.display='inline'; Codehighlighter1_296_314_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_296_314_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_296_314_Closed_Text.style.display='none'; Codehighlighter1_296_314_Open_Image.style.display='inline'; Codehighlighter1_296_314_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_296_314_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_296_314_Open_Text><span style="COLOR: #000000">{ok,[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">],[]}</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> N </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> rfc4627:encode(</span><span style="COLOR: #000000">12345</span><span style="COLOR: #000000">).   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">12345</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">  <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">6</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> rfc4627:decode(N).   <br><img id=Codehighlighter1_387_399_Open_Image onclick="this.style.display='none'; Codehighlighter1_387_399_Open_Text.style.display='none'; Codehighlighter1_387_399_Closed_Image.style.display='inline'; Codehighlighter1_387_399_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_387_399_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_387_399_Closed_Text.style.display='none'; Codehighlighter1_387_399_Open_Image.style.display='inline'; Codehighlighter1_387_399_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_387_399_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_387_399_Open_Text><span style="COLOR: #000000">{ok,</span><span style="COLOR: #000000">12345</span><span style="COLOR: #000000">,[]}</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> S </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> rfc4627:encode(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">12345</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">).   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">[49,50,51,52,53]</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">  <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> rfc4627:decode(S).   <br><img id=Codehighlighter1_485_499_Open_Image onclick="this.style.display='none'; Codehighlighter1_485_499_Open_Text.style.display='none'; Codehighlighter1_485_499_Closed_Image.style.display='inline'; Codehighlighter1_485_499_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_485_499_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_485_499_Closed_Text.style.display='none'; Codehighlighter1_485_499_Open_Image.style.display='inline'; Codehighlighter1_485_499_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_485_499_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_485_499_Open_Text><span style="COLOR: #000000">{ok,</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">12345</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,[]}</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> T </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> rfc4627:encode(</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">).   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">true</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">  <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> rfc4627:decode(T).   <br><img id=Codehighlighter1_571_582_Open_Image onclick="this.style.display='none'; Codehighlighter1_571_582_Open_Text.style.display='none'; Codehighlighter1_571_582_Closed_Image.style.display='inline'; Codehighlighter1_571_582_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_571_582_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_571_582_Closed_Text.style.display='none'; Codehighlighter1_571_582_Open_Image.style.display='inline'; Codehighlighter1_571_582_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_571_582_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_571_582_Open_Text><span style="COLOR: #000000">{ok,</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">,[]}</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">11</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> F </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> rfc4627:encode(</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">).   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">false</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">  <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">12</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> rfc4627:decode(F).   <br><img id=Codehighlighter1_657_669_Open_Image onclick="this.style.display='none'; Codehighlighter1_657_669_Open_Text.style.display='none'; Codehighlighter1_657_669_Closed_Image.style.display='inline'; Codehighlighter1_657_669_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_657_669_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_657_669_Closed_Text.style.display='none'; Codehighlighter1_657_669_Open_Image.style.display='inline'; Codehighlighter1_657_669_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_657_669_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_657_669_Open_Text><span style="COLOR: #000000">{ok,</span><span style="COLOR: #0000ff">false</span><span style="COLOR: #000000">,[]}</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">13</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> Null </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> rfc4627:encode(</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">).   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">null</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">  <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">14</span><span style="COLOR: #000000">></span><span style="COLOR: #000000"> rfc4627:decode(Null).   <br><img id=Codehighlighter1_748_759_Open_Image onclick="this.style.display='none'; Codehighlighter1_748_759_Open_Text.style.display='none'; Codehighlighter1_748_759_Closed_Image.style.display='inline'; Codehighlighter1_748_759_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_748_759_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_748_759_Closed_Text.style.display='none'; Codehighlighter1_748_759_Open_Image.style.display='inline'; Codehighlighter1_748_759_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_748_759_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_748_759_Open_Text><span style="COLOR: #000000">{ok,</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">,[]}</span></span><span style="COLOR: #000000">  <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span></div> <br> <img src ="http://www.shnenglu.com/keigoliye/aggbug/96647.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/keigoliye/" target="_blank">暗夜教父</a> 2009-09-18 15:38 <a href="http://www.shnenglu.com/keigoliye/archive/2009/09/18/96647.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Flash Socket ?Erlang Socket 通信的注意事?/title><link>http://www.shnenglu.com/keigoliye/archive/2009/09/18/96634.html</link><dc:creator>暗夜教父</dc:creator><author>暗夜教父</author><pubDate>Fri, 18 Sep 2009 04:40:00 GMT</pubDate><guid>http://www.shnenglu.com/keigoliye/archive/2009/09/18/96634.html</guid><wfw:comment>http://www.shnenglu.com/keigoliye/comments/96634.html</wfw:comment><comments>http://www.shnenglu.com/keigoliye/archive/2009/09/18/96634.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/keigoliye/comments/commentRss/96634.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/keigoliye/services/trackbacks/96634.html</trackback:ping><description><![CDATA[<p>转自<a >http://www.javaeye.com/topic/401041</a><br><br><br>学erlang有一D|间了Q现在在l护一套webimpȝ <br>q打扩展成 webgame 的服务程?/p> <p>在没有用包协议的时候,遇到好多_包问题Q实在恼?/p> <p>查阅了相兌料:</p> <p>Flash Socket ?writeUTF() 会自动增加包头长度的协议Q刚好对应了 <br>Erlang的Socket选项 {packet,2} <br><br>q得两者的通信非常完美Q再也不用担心粘包什么的问题?/p> <p> </p> <p>下面是我写的一个Flash Socket 接口QSocketBridge.as</p> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id=Codehighlighter1_8_2502_Open_Image onclick="this.style.display='none'; Codehighlighter1_8_2502_Open_Text.style.display='none'; Codehighlighter1_8_2502_Closed_Image.style.display='inline'; Codehighlighter1_8_2502_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_8_2502_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_8_2502_Closed_Text.style.display='none'; Codehighlighter1_8_2502_Open_Image.style.display='inline'; Codehighlighter1_8_2502_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedBlock.gif" align=top><span style="COLOR: #0000ff">package</span><span style="COLOR: #000000"> </span><span id=Codehighlighter1_8_2502_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_8_2502_Open_Text><span style="COLOR: #000000">{   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>    </span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> flash.display.Sprite;   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>    </span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> flash.events.</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">;   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>    </span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> flash.net.Socket;   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>    </span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> flash.utils.</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">;   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>    </span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> flash.external.ExternalInterface;   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>    </span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> flash.system.</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">;   <br><img id=Codehighlighter1_263_2497_Open_Image onclick="this.style.display='none'; Codehighlighter1_263_2497_Open_Text.style.display='none'; Codehighlighter1_263_2497_Closed_Image.style.display='inline'; Codehighlighter1_263_2497_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_263_2497_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_263_2497_Closed_Text.style.display='none'; Codehighlighter1_263_2497_Open_Image.style.display='inline'; Codehighlighter1_263_2497_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000"> SocketBridge </span><span style="COLOR: #0000ff">extends</span><span style="COLOR: #000000"> Sprite </span><span id=Codehighlighter1_263_2497_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_263_2497_Open_Text><span style="COLOR: #000000">{   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        Socket.prototype.timeout    </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">3000</span><span style="COLOR: #000000">;   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> var socket:Socket;   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> function SocketBridge()   <br><img id=Codehighlighter1_402_1096_Open_Image onclick="this.style.display='none'; Codehighlighter1_402_1096_Open_Text.style.display='none'; Codehighlighter1_402_1096_Closed_Image.style.display='inline'; Codehighlighter1_402_1096_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_402_1096_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_402_1096_Closed_Text.style.display='none'; Codehighlighter1_402_1096_Open_Image.style.display='inline'; Codehighlighter1_402_1096_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>        </span><span id=Codehighlighter1_402_1096_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_402_1096_Open_Text><span style="COLOR: #000000">{   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>            socket </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> Socket();   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>            socket.addEventListener( Event.CONNECT, onConnect );   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>            socket.addEventListener( ProgressEvent.SOCKET_DATA, onDataRecevice);   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>            socket.addEventListener( Event.CLOSE, onClose);   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>            socket.addEventListener( IOErrorEvent.IO_ERROR, onError);    <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>               <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>            </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(ExternalInterface.available)   <br><img id=Codehighlighter1_809_1083_Open_Image onclick="this.style.display='none'; Codehighlighter1_809_1083_Open_Text.style.display='none'; Codehighlighter1_809_1083_Closed_Image.style.display='inline'; Codehighlighter1_809_1083_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_809_1083_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_809_1083_Closed_Text.style.display='none'; Codehighlighter1_809_1083_Open_Image.style.display='inline'; Codehighlighter1_809_1083_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>            </span><span id=Codehighlighter1_809_1083_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_809_1083_Open_Text><span style="COLOR: #000000">{   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>                   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>                ExternalInterface.addCallback(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">socket_connect</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,socket_connect);   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>                ExternalInterface.addCallback(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">socket_send</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,socket_send);   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>                ExternalInterface.addCallback(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">load_policy</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,load_policy);   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>            }</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>        }</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> function onError(e):</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">  <br><img id=Codehighlighter1_1151_1255_Open_Image onclick="this.style.display='none'; Codehighlighter1_1151_1255_Open_Text.style.display='none'; Codehighlighter1_1151_1255_Closed_Image.style.display='inline'; Codehighlighter1_1151_1255_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_1151_1255_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1151_1255_Closed_Text.style.display='none'; Codehighlighter1_1151_1255_Open_Image.style.display='inline'; Codehighlighter1_1151_1255_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>        </span><span id=Codehighlighter1_1151_1255_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_1151_1255_Open_Text><span style="COLOR: #000000">{   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>            ExternalInterface.call(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">sb_onerror</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,e.text);   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>            socket.close();   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>        }</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> function load_policy(host:String,port):</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">  <br><img id=Codehighlighter1_1329_1414_Open_Image onclick="this.style.display='none'; Codehighlighter1_1329_1414_Open_Text.style.display='none'; Codehighlighter1_1329_1414_Closed_Image.style.display='inline'; Codehighlighter1_1329_1414_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_1329_1414_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1329_1414_Closed_Text.style.display='none'; Codehighlighter1_1329_1414_Open_Image.style.display='inline'; Codehighlighter1_1329_1414_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>        </span><span id=Codehighlighter1_1329_1414_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_1329_1414_Open_Text><span style="COLOR: #000000">{   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>            Security.loadPolicyFile(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">xmlsocket://</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">host</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">port);     <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>        }</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>           <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> function socket_connect(host:String,port):</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">  <br><img id=Codehighlighter1_1503_1689_Open_Image onclick="this.style.display='none'; Codehighlighter1_1503_1689_Open_Text.style.display='none'; Codehighlighter1_1503_1689_Closed_Image.style.display='inline'; Codehighlighter1_1503_1689_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_1503_1689_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1503_1689_Closed_Text.style.display='none'; Codehighlighter1_1503_1689_Open_Image.style.display='inline'; Codehighlighter1_1503_1689_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>        </span><span id=Codehighlighter1_1503_1689_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_1503_1689_Open_Text><span style="COLOR: #000000">{   <br><img id=Codehighlighter1_1523_1586_Open_Image onclick="this.style.display='none'; Codehighlighter1_1523_1586_Open_Text.style.display='none'; Codehighlighter1_1523_1586_Closed_Image.style.display='inline'; Codehighlighter1_1523_1586_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_1523_1586_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1523_1586_Closed_Text.style.display='none'; Codehighlighter1_1523_1586_Open_Image.style.display='inline'; Codehighlighter1_1523_1586_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>            </span><span style="COLOR: #0000ff">try</span><span id=Codehighlighter1_1523_1586_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_1523_1586_Open_Text><span style="COLOR: #000000">{   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>                socket.connect(host,port);   <br><img id=Codehighlighter1_1595_1676_Open_Image onclick="this.style.display='none'; Codehighlighter1_1595_1676_Open_Text.style.display='none'; Codehighlighter1_1595_1676_Closed_Image.style.display='inline'; Codehighlighter1_1595_1676_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_1595_1676_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1595_1676_Closed_Text.style.display='none'; Codehighlighter1_1595_1676_Open_Image.style.display='inline'; Codehighlighter1_1595_1676_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>            }</span></span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000">(e)</span><span id=Codehighlighter1_1595_1676_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_1595_1676_Open_Text><span style="COLOR: #000000">{   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>                ExternalInterface.call(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">sb_onerror</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,e.text);   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>            }</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>        }</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>           <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> function socket_send(msg:String)   <br><img id=Codehighlighter1_1765_1849_Open_Image onclick="this.style.display='none'; Codehighlighter1_1765_1849_Open_Text.style.display='none'; Codehighlighter1_1765_1849_Closed_Image.style.display='inline'; Codehighlighter1_1765_1849_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_1765_1849_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1765_1849_Closed_Text.style.display='none'; Codehighlighter1_1765_1849_Open_Image.style.display='inline'; Codehighlighter1_1765_1849_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>        </span><span id=Codehighlighter1_1765_1849_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_1765_1849_Open_Text><span style="COLOR: #000000">{      <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>            socket.writeUTF(msg);   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>            socket.flush();   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>        }</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>           <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> function onConnect(event:Event):</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">    <br><img id=Codehighlighter1_1931_2004_Open_Image onclick="this.style.display='none'; Codehighlighter1_1931_2004_Open_Text.style.display='none'; Codehighlighter1_1931_2004_Closed_Image.style.display='inline'; Codehighlighter1_1931_2004_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_1931_2004_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_1931_2004_Closed_Text.style.display='none'; Codehighlighter1_1931_2004_Open_Image.style.display='inline'; Codehighlighter1_1931_2004_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>        </span><span id=Codehighlighter1_1931_2004_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_1931_2004_Open_Text><span style="COLOR: #000000">{   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>            ExternalInterface.call(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">sb_onconnect</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">);   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>        }</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>           <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> function onClose(event:Event):</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">    <br><img id=Codehighlighter1_2084_2186_Open_Image onclick="this.style.display='none'; Codehighlighter1_2084_2186_Open_Text.style.display='none'; Codehighlighter1_2084_2186_Closed_Image.style.display='inline'; Codehighlighter1_2084_2186_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_2084_2186_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_2084_2186_Closed_Text.style.display='none'; Codehighlighter1_2084_2186_Open_Image.style.display='inline'; Codehighlighter1_2084_2186_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>        </span><span id=Codehighlighter1_2084_2186_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_2084_2186_Open_Text><span style="COLOR: #000000">{   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>            socket.close();   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>            ExternalInterface.call(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">sb_onclose</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,</span><span style="COLOR: #0000ff">true</span><span style="COLOR: #000000">);   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>        }</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>  <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>        </span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000"> function onDataRecevice( eventrogressEvent ):</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">  <br><img id=Codehighlighter1_2270_2485_Open_Image onclick="this.style.display='none'; Codehighlighter1_2270_2485_Open_Text.style.display='none'; Codehighlighter1_2270_2485_Closed_Image.style.display='inline'; Codehighlighter1_2270_2485_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_2270_2485_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_2270_2485_Closed_Text.style.display='none'; Codehighlighter1_2270_2485_Open_Image.style.display='inline'; Codehighlighter1_2270_2485_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>        </span><span id=Codehighlighter1_2270_2485_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_2270_2485_Open_Text><span style="COLOR: #000000">{   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>            var sdata:String;   <br><img id=Codehighlighter1_2348_2472_Open_Image onclick="this.style.display='none'; Codehighlighter1_2348_2472_Open_Text.style.display='none'; Codehighlighter1_2348_2472_Closed_Image.style.display='inline'; Codehighlighter1_2348_2472_Closed_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_2348_2472_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_2348_2472_Closed_Text.style.display='none'; Codehighlighter1_2348_2472_Open_Image.style.display='inline'; Codehighlighter1_2348_2472_Open_Text.style.display='inline';" src="http://www.shnenglu.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>            </span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(socket.bytesAvailable)</span><span id=Codehighlighter1_2348_2472_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_2348_2472_Open_Text><span style="COLOR: #000000">{   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>                sdata </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> socket.readUTF();   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>                ExternalInterface.call(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">sb_ondata</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,sdata);   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>            }</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>        }</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>  <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>    }</span></span><span style="COLOR: #000000">   <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">  <br><img src="http://www.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span></div> <img src ="http://www.shnenglu.com/keigoliye/aggbug/96634.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/keigoliye/" target="_blank">暗夜教父</a> 2009-09-18 12:40 <a href="http://www.shnenglu.com/keigoliye/archive/2009/09/18/96634.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>erlang|络~程的几个性能调优和注意点http://www.shnenglu.com/keigoliye/archive/2009/09/14/96106.html暗夜教父暗夜教父Mon, 14 Sep 2009 04:25:00 GMThttp://www.shnenglu.com/keigoliye/archive/2009/09/14/96106.htmlhttp://www.shnenglu.com/keigoliye/comments/96106.htmlhttp://www.shnenglu.com/keigoliye/archive/2009/09/14/96106.html#Feedback0http://www.shnenglu.com/keigoliye/comments/commentRss/96106.htmlhttp://www.shnenglu.com/keigoliye/services/trackbacks/96106.html
前些天给echo_server写了个非常简单的q接压力试E序,

   1.  -module(stress_test).  
   
2.   
   
3-export([start/0, tests/1]).  
   
4.   
   
5. start() ->  
   
6.     tests(12345).  
   
7.   
   
8. tests(Port) ->  
   
9.     io:format("starting~n"),  
  
10.     spawn(fun() -> test(Port) end),  
  
11.     spawn(fun() -> test(Port) end),  
  
12.     spawn(fun() -> test(Port) end),  
  
13.     spawn(fun() -> test(Port) end).  
  
14.   
  
15. test(Port) ->  
  
16.      case gen_tcp:connect("192.168.0.217", Port, [binary,{packet, 0}]) of  
  
17.     {ok, _} ->  
  
18.             test(Port);  
  
19.     _ ->  
  
20.         test(Port)  
  
21.     end.  
一开始我的这个stress_test客户端运行在windows上面, echo_server服务器端q行在linux上面? l果接受?016个连接就停止? 于是我用ulimit -n 改了服务器端的文件描q符数量?0240. 接着q是如此,折腾了几?最l还是没有搞明白?

于是求助于公司的linux~程牛h,l果让我一?..  客户端没有修Ҏ件描q符个数. windows上得在注册表里面?
牛h开始对q东西的性能感兴了,刚好我摸了一阵子erlang的文?于是我俩p向了erlang|络q接的性能调优之旅啦~~q程真是让h兴奋?我们很快通过?024q一关~~C4999个连?很兴?

但ؓ什?999个连接呢, 查一下代码终于发现echo_server.erl定义了一个宏, 最大连接数?000. 我又倒~~
修改~译之后, q接数跑?01xx多了, 太哈皮了!
再测102400个连接时,?2767个连接数erl挂了~说是q程开得太多了. 好在记得q个erl的参?P,可以定义erlang能生成的q程? 默认?2768. 改了!

后面不知怎么着,?1231个连接停止了. 新的性能瓉又卡了我?  好在牛h对linux? 用strace(q东西会莫名地退?, stap查出一些苗?   我也惛_在otp文档好像提过另一个limit,那就是端口数...在此同时我们发现erlang在linux上是用的传统poll模型. 但查erlang的源代码发现是支持epoll? 在网上搜了半?l于搜到了个maillist的帖?

代码
  1. $./configure --enable-kernel-poll  

׃我们的测试服务器是双核的,我们在配|的时候也打开了smp支持.  Ƣ快的make  & make install之后....
?/proc/sys/net/ipv4/ip_local_port_range 的内Ҏ成了1024?5535.  最多也也能Ҏ65535 :)

代码
  1. $echo 1024 65535 > ip_local_port_range  

另外再添加一个erl的环境变?br>
代码
  1. $export ERL_MAX_PORTS=102400  

于是开始跑?不过q次跑不一样了
echo_server
 
  1. $erl -noshell  +P 102400 +K true +S 2 -smp -s echo_server start  
   
stress_test
 
  1. $erl -noshell  +P 102400 +K true +S 2 -smp -s stress_test start  
q里?K true,表示使用内核poll,+S 2 表示两个? q样可欢快啦~~~ 10w大关q咯! 而且比刚才没用epoll的速度快暴多~~
于是我们又开始了204800个连接发试了~~~

用top一看cpu占用率极?服务器只?%左右?内存也不是很大~~



暗夜教父 2009-09-14 12:25 发表评论
]]>
echo_server http://www.shnenglu.com/keigoliye/archive/2009/09/14/96105.html暗夜教父暗夜教父Mon, 14 Sep 2009 04:24:00 GMThttp://www.shnenglu.com/keigoliye/archive/2009/09/14/96105.htmlhttp://www.shnenglu.com/keigoliye/comments/96105.htmlhttp://www.shnenglu.com/keigoliye/archive/2009/09/14/96105.html#Feedback0http://www.shnenglu.com/keigoliye/comments/commentRss/96105.htmlhttp://www.shnenglu.com/keigoliye/services/trackbacks/96105.html
   1.  -module(echo_server).  
   
2-export([start/0,stop/0]).  
   
3.   
   
4-define(LISTEN_PORT,12345).     % 开攄?nbsp; 
   
5-define(MAX_CONN, 5000).        % 最大连接数  
   
6.   
   
7. start() ->  
   
8.     process_flag(trap_exit, true), % 讄退出陷?nbsp; 
   
9.     tcp_server:start_raw_server(?LISTEN_PORT,  
  
10.                 fun(Socket) -> socket_handler(Socket,self()) end,  
  
11.                 ?MAX_CONN,   
  
12.                 0).  
  
13.   
  
14%% 处理数据  
  
15. socket_handler(Socket,Controller) ->  
  
16.     receive  
  
17.         {tcp, Socket, Bin} ->  
  
18.             gen_tcp:send(Socket, Bin); % echo  
  
19.         {tcp_closed, Socket} ->  
  
20.             ok;  
  
21.         _ ->  
  
22.             socket_handler(Socket,Controller)  
  
23.     end.  
  
24.   
  
25. stop() ->  
  
26.     tcp_server:stop(?LISTEN_PORT).  

ZJoe Armstrong 的tcp_server模块来做? 试试?:)

~译
    erl -noshell -s make all -s init stop
q行
    erl -noshell -sname coderplay -s echo_server start


暗夜教父 2009-09-14 12:24 发表评论
]]>
erlang |络调优实战http://www.shnenglu.com/keigoliye/archive/2009/09/14/96096.html暗夜教父暗夜教父Mon, 14 Sep 2009 03:20:00 GMThttp://www.shnenglu.com/keigoliye/archive/2009/09/14/96096.htmlhttp://www.shnenglu.com/keigoliye/comments/96096.htmlhttp://www.shnenglu.com/keigoliye/archive/2009/09/14/96096.html#Feedback0http://www.shnenglu.com/keigoliye/comments/commentRss/96096.htmlhttp://www.shnenglu.com/keigoliye/services/trackbacks/96096.htmlerlang|络~程的几个性能调优和注意点
原文作者:coderplay
前些天给echo_server写了个非常简单的q接压力试E序,
下蝲: stress_test.erl
  • -module(stress_test).  

  • -export([start/0, tests/1]).  

  • start() ->  

  • tests(12345).  

  • tests(Port) ->  

  • io:format("starting~n"),  

  • spawn(fun() -> test(Port)
    end),  

  • spawn(fun() -> test(Port)
    end),  

  • spawn(fun() -> test(Port)
    end),  

  • spawn(fun() -> test(Port)
    end).  

  • test(Port) ->  

  • case
    gen_tcp:connect("192.168.0.217", Port, [binary,{packet, 0}])
    of
  •     {ok, _} ->  

  • test(Port);  

  • _ ->  

  • test(Port)

  • end.

一开始我的这个stress_test客户端运行在windows上面,echo_server服务器端q行在linux上面。结果接受了1016个连接就停止? 于是我用ulimit -n改了服务器端?span onclick="tagshow(event)" class="t_tag">文g描述W数量ؓ10240. 接着q是如此,折腾了几?最l还是没有搞明白?br> 于是求助于公司的linux~程牛h,l果让我一?#8230;  客户端没有修Ҏ件描q符个数. windows上得在注册表里面?

牛h开始对q东西的性能感兴了,刚好我摸了一阵子erlang?span onclick="tagshow(event)" class="t_tag">文档,于是我俩p向了erlang|络q接的性能调优之旅啦~~q程真是让h兴奋?我们很快通过?024q一关~~C4999个连?很兴?
但ؓ什?999个连接呢, 查一下代码终于发现echo_server.erl定义了一个宏, 最大连接数?000. 我又倒~~
修改~译之后, q接数跑?01xx多了, 太哈皮了!
再测102400个连接时,?2767个连接数erl挂了~说是q程开得太多了. 好在记得q个erl的参?P,可以定义erlang能生成的q程? 默认?2768. 改了!
后面不知怎么着,?1231个连接停止了. 新的性能瓉又卡了我? 好在牛h对linux? 用strace(q东西会莫名地退?,stap查出一些苗?我也惛_在otp文档好像提过另一个limit,那就是端口数…在此同时我们发现 erlang在linux上是用的传统poll模型.但查erlang的源代码发现是支持epoll? 在网上搜了半?l于搜到了个maillist的帖?
  • $./configure --enable-kernel-poll

׃我们的测试服务器是双核的,我们在配|的时候也打开了smp支持. Ƣ快的make  & make install之后….
?/proc/sys/net/ipv4/ip_local_port_range 的内Ҏ成了1024?5535. 最多也也能Ҏ65535
  • $echo 1024 65535 > ip_local_port_range

另外再添加一个erl的环?span onclick="tagshow(event)" class="t_tag">变量
  • $export ERL_MAX_PORTS=102400

于是开始跑?不过q次跑不一样了
echo_server
  • $erl -noshell  +P 102400 +K true +S 2 -smp -s echo_server start

stress_test
  • $erl -noshell  +P 102400 +K true +S 2 -smp -s stress_test start

q里?K true,表示使用内核poll,+S 2 表示两个? q样可欢快啦~~~ 10w大关q咯! 而且比刚才没用epoll的速度快暴多~~
于是我们又开始了204800个连接发试了~~~
用top一看cpu占用率极?服务器只?%左右。内存也不是很大~~

暗夜教父 2009-09-14 11:20 发表评论
]]>
ErLang语法提要http://www.shnenglu.com/keigoliye/archive/2009/09/11/95894.html暗夜教父暗夜教父Fri, 11 Sep 2009 03:04:00 GMThttp://www.shnenglu.com/keigoliye/archive/2009/09/11/95894.htmlhttp://www.shnenglu.com/keigoliye/comments/95894.htmlhttp://www.shnenglu.com/keigoliye/archive/2009/09/11/95894.html#Feedback0http://www.shnenglu.com/keigoliye/comments/commentRss/95894.htmlhttp://www.shnenglu.com/keigoliye/services/trackbacks/95894.html
ErLang的注释用%开头。ErLang用下划线“_”表示L变量Q类gJava的switch语法里面的default选项?

ErLangp于PrologQ不q,我觉得,ErLang语法和Haskell语法比较象,都是采用 -> 定义函数?

ErLang语句中的标点W号用法很象文章的标点符受?

整个函数定义l束用一个句?#8220;.”Q同一个函CQƈ列的逻辑分支之间Q用分号“;”分界Q顺序语句之_用逗号“,”分隔?

ErLang中,{ }不是表示E序块的开头和l尾Q而是表示一U特D的数据l构cd——TupleQ元l)Q比如,{12, 3, ok}。我们可以把Tuple理解为定长数l?

[ ] 则表C最基本的函数式~程的数据结构类型——List。List数据l构很基本,写法和用法也有一定的复杂度,不是表面上看h那么单,后面讲解Closure的章节会详细介绍List的最基本的构造原理?

下面我们来看一个简单的例子?

我们首先定义一个最单的函数Q把一个参C?0Q然后加1?
times10( Number ) –>
Temp = 10 * Number,
Temp + 1.

Z说明问题Q上面的代码把乘法操作和加法操作分成两个步骤。Temp = 10 * Number语句后面是逗号Q因是两条顺序执行的语句。Temp + 1语句后面是句P表示整个函数定义l束。而且Q可以看出,ErLang没有return语句Q最后执行的那条语句的执行结果就是返回倹{?

下面Q我们把q个函数优化一下。当参数{于0的时候,直接q?Q否则,׃?0Q然后加1Q然后返回。这时候,我们p用到case of逻辑分支语句Q相当于java的switch语句?

times10( Number ) –>
case Number of
0 -> 1;
_ ->
Temp = 10 * Number,
Temp + 1
end.

我们来仔l观察这DErLangE序?

当Number{于0的时候,直接q回1。由于这是一条分支语句,和后面的分支是ƈ列的关系Q所以,1的后面的标点W号是分受后面这个分支,下划U?#8220;_”表示M其它|q里pC除?之外的Q何其它数倹{?

需要注意的一ҎQcase of语句需要用endl尾Qend之前不需要有标点W号?

上述代码中的case of 语句Q其实就是Pattern Match的一U。ErLang的Pattern Match很强大,能够大幅度简化程序逻辑Q后面进行专门介l?
Pattern Match
Pattern Match主要有两个功能——比较分z֒变量赋倹{?
其中Q比较分z是最主要的功能。比较分z意思是Q根据参数D行条件分支的分派。可以把比较分派功能看作是一U类gif, else{条件分支语句的z强大写法?
上面的例子中Qcase Number of 是ҎNumber的D行比较分z。更常见的写法是Q可以把Pattern Match部分提到函数定义分支的高度。于是,上述代码可以写成下面的Ş式:
times10( 0 ) –> 1;
times10( Number ) –>
Temp = 10 * Number,
Temp + 1.

q段代码׃个函数定义分支构成,׃两个函数分支的函数名相同Q而且参数个数相同Q而且两个函数定义分支之间采用分号“;”分隔Q说明这是同一个函数的定义。函数式~程语言中,q种定义方式很常见,看v来Ş式很整齐Q宛如数学公式?

q段代码的含义是Q当参数值等?的时候,那么Q程序走W一个函数定义分支(卛_?#8220;;”l尾?#8220;times10( 0 ) –> 1;”Q,否则Q走下面的函数定义分支(?#8220;times10( Number ) –>…”Q?

W二个分支中的参C是一个常敎ͼ而是一个变量NumberQ表C个分支可以接受Q何除?之外的参数|比如Q???2{等Q这些值将赋给变量Number?
因此Q这个地方也体现了Pattern Match的第二个功能——变量赋倹{?

Pattern Match的Ş式可以很复杂Q下面D几个典型的例子?
Q?Q数据结构拆解赋?
前面到了ErLang语言有一U相当于定长数组的TuplecdQ我们可以很方便地根据元素的位置q行q行赋倹{比如,
{First, Second} = {1, 2}
我们q可以对复合Tuple数据l构q行赋|比如
{A, {B, C}, D} = { 1, {2, 3}, 4 }
List数据l构的赋g是类伹{由于List的写法和用法不是那么单,三言两语也说不清楚,q徒增困扎ͼq里不再赘述?
Q?QassertEquals语句
在Java{语a中,我们写单元测试的时候,会写一些assert语句Q验证程序运行结果。这些assert语句通常是以API的方式提供,比如QassertTrue()、assertEquals(){?
在ErLang中,可以用简单的语句辑ֈcM于assertTrue()、assertEquals(){API的效果?
比如QErLang中,true = testA() q样的语句表CtestA的返回结果必LtrueQ否则就会抛出异常。这个用法很巧妙。这里解释一下?
前面讲过QErLang语法U定Q小写字母开头的名字Q都是常量名。这里的true自然也是一个常量,既然是常量,我们不可能对它赋|那么true = testA()的意思就不是赋|而是q行匚w比较?
Q?Q匹配和赋值同时进?
我们来看q样一D代码?
case Result of
{ok, Message} -> save(Message);
{error, ErrorMessage} -> log(ErrorMessage)
end.

q段代码中,Result是一个TuplecdQ包含两个元素,W一个元素表C成功(okQ或者失败(errorQ,W二个元素表C具体的信息?
可以看到Q这两个条g分支中,同时出现了常量和变量。第一个条件分支中的ok是常量,Message是变量;W二个条件分支中的error是常量,ErrorMessage是变量?
q两个条件分支都既有比较判断Q也有变量赋倹{首先,判断ResultTuple中的W一个元素和哪一个分支的W一个元素匹配,如果盔RQ那么把ResultTuple中的W二个元素赋l这个分支的W二个变量元素。即Q如果Result的第一个元素是okQ那么走W一个条件分支,q且把Result的第二个元素赋给Message变量Q如果Result的第二个元素是errorQ那么走W二个条件分支,q且把Result的第二个元素赋给ErrorMessage变量?

在Java{语a中,实现上述的条件分支逻辑Q则需要多写几条语句ErLang语法可以从Ş式上化和简化逻辑分支分派复杂的程序?
除了支持数相{比较,Pattern Matchq可以进行范围比较、大比较等Q需要用到关键字whenQ不q用到when的情况,比if elsez不了多,q里不再赘述?
匿名函数
ErLang允许在一个函C内部定义另一个匿名函敎ͼq是函数式编E的最基本的功能。这P函数式语a才可以支持Closure。我们来看一个ErLang的匿名函数的例子?
outer( C ) –>
Inner = fun(A, B) -> A + B + C end,
Inner(2, 3).

q段代码首先定义了一个命名函数outerQ然后在outer函数内部定义了一个匿名函数。可以看刎ͼq个匿名函数采用关键字fun来定义。前面讲q,函数式编E的函数q当于面向对象~程的类实例对象Q匿名函数自然也是这P也相当于cd例,我们可以把这个匿名函数赋l一个变量InnerQ然后我们还可以把这个变量当作函数来调用Q比如,Inner(2, 3)?
fun是ErLang用来定义匿名函数的关键字。这个关键字很重要。fun定义匿名函数的用法不是很复杂Q和命名函数定义cM?
函数分支的定义也是类|只是需要用endl尾Q而不是用句号“.”l尾Q而且fun只需要写一ơ,不需要向命名函数那样Q每个分支都要写。比如,
MyFunction = fun(0) -> 0;
(Number) -> Number * 10 + 1 end,
MyFunction(3),
函数作ؓ变量
匿名函数可以当作对象赋给变量Q命名函数同样也可以赋给变量。具体用法还是需要借助重要的fun关键字。比如,
MyFunction = fun outer / 1

可以把上述定义的outer函数赋给MyFunction变量。后面的 / 0表示q个outer函数只有一个参数。因为ErLang允许有多个同名函数的定义Q只要参CC同,是不同的函数?
我们可以看到QQ何函数都可以作ؓ变量Q也可以作ؓ参数和返回g来传去,q些变量也可以随时作为函数进行调用,于是具有了一定的动态性?
函数的动态调?
ErLang有一个apply函数Q可以动态调用某一个函数变量?
基本用法?apply( 函数变量Q函数参数列?)。比如,上面的MyFunciton函数变量Q就可以q么调用Qapply( MyFunction, [ 5 ])?
那么我们能否Ҏ一个字W串作ؓ函数名获取一个函数变量呢Q这h们就可以Ҏ一个字W串来动态调用某个函C?
ErLang中,做到q一点很单。前面讲q,函数名一旦定义了Q自然就固定了,q也cM于常量名Q属于不可变的atomQ原子)。所有的atom都可以{换成字符Ԍ也可以从字符串{换过来。ErLang中的字符串实质上都是List。字W串和atom之间的{换通过list_to_atom和atom_to_list来{换?
于是我们可以q样获取MyFuncitonQMyFunction = list_to_atom(“outer”)
如果outer函数已经定义Q那么MyFucntionq于outer函数Q如果outer函数没有定义Q那么list_to_atom(“outer”)会生一个新的叫做outer的atomQMyFucntionq于这个新产生的atom?
如果需要强制生一个已l存在的atomQ那么我们需要调用list_to_existing_atom转换函数Q这个函C会生新的atomQ而是q回一个已l存在了的atom?
Tuple作ؓ数据成员集合
前面讲解函数式编E特性的时候,提到了函数式~程没有面向对象~程的成员变量,q是一个限制?
ErLang的Tuplecd可以一定程度克服这个限制。Tuple可以一定程度上担当容纳成员变量的职责?
面向对象的类定义Q其实就是一数据和函数的集合,只是集合的成员之间都有一个this指针相关联,可以怺扑ֈ?
ErLang的Tuplecd是数据的集合,可以很自然地发挥成员变量的作用,比如Q{Member1, Member2}?
读者可能会_ErLang的函C可以作ؓ变量Q也可以攑ֈTuple里面Q比如, { Memer1, Member2, Funtion1, Function2}。这不就和面向对象编E一样了吗?
遗憾的是Q这样做是得不偿q。因为函数式~程没有面向对象的那U内在的this指针支持Q自然也没有内在的多态和l承支持Q硬把数据和函数p合在一个Tuple里面Q一点好处都没有Q而且q׃函数作ؓ实例对象的灵zL?
所以,函数式编E的最佛_践(Best PracticeQ应该是QTuple用来容纳成员数据Q函数操作Tuple。Tuple定义和函数定义加在一P构成了松散的数据结构,功能上类g面向对象的类定义。Tuple + 函数的数据结构,h多态的Ҏ,因ؓ函数本n能够作ؓ变量替换Q但是不hl承的特性,因ؓ没有this指针的内在支持?
正是因ؓTuple在数据类型构造方面的重大作用Q所以,ErLang专门引入了一U叫做Record的宏定义Q可以对Tuple的数l下标位|命名。比如,把第一个元素叫做AddressQ第二个元素叫做ZipcodeQ这L序员可以这些名字访问Tuple里面的元素,而不需要按照数l下标位|来讉K?
Tuple和Record的具体用法还是有一定复杂度Q限于篇q,本章没有展开说明Q只提了一些原理方面的要点?
其它
ErLangq有其它语法Ҏ和l节Q不再一一赘述。有兴趣的读者,可以自行去ErLang|站Qwww.erlang.orgQ进行研I?

暗夜教父 2009-09-11 11:04 发表评论
]]>
Erlang入门Q五Q——补?/title><link>http://www.shnenglu.com/keigoliye/archive/2009/09/11/95888.html</link><dc:creator>暗夜教父</dc:creator><author>暗夜教父</author><pubDate>Fri, 11 Sep 2009 02:16:00 GMT</pubDate><guid>http://www.shnenglu.com/keigoliye/archive/2009/09/11/95888.html</guid><wfw:comment>http://www.shnenglu.com/keigoliye/comments/95888.html</wfw:comment><comments>http://www.shnenglu.com/keigoliye/archive/2009/09/11/95888.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/keigoliye/comments/commentRss/95888.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/keigoliye/services/trackbacks/95888.html</trackback:ping><description><![CDATA[<span style="FONT-WEIGHT: bold">1。Erlang的保留字</span>有:<br> <p>after and andalso band begin bnot bor bsl bsr bxor case catch cond div end fun if let not of or orelse query receive rem try when xor<a name=1.6><!----></a> </p> 基本都是些用于逻辑q算、位q算以及Ҏ表达式的W号<br><br><span style="FONT-WEIGHT: bold">2.Erlang的类?/span>Q除了在前面入门一提到的类型外Q还包括Q?br>1)BinaryQ用于表C某D|知类型的内存区域<br>比如Q?br>1> <strong><<10,20>>.</strong> <br><<10,20>> <br>2> <strong><<"ABC">>.</strong><br> <<65,66,67>> <br><br>2QReferenceQ通过调用mk_ref/0产生的运行时的unique term<br><br>3)StringQ字W串QErlang中的字符串用双引号包括v来,其实也是list。编译时期,两个邻近的字W串被q接hQ比?string" "42" {h?"string42"<br><br>4)RecordQ记录类型,与c语言中的structcMQ模块可以通过-record属性声明,比如Q?br>-module(person). <br>-export([new/2]).<br>-record(person, {name, age}). <br>new(Name, Age) -><br>     #person{name=Name, age=Age}. <br>1> <strong>person:new(dennis, 44).</strong> <br>{person,dennis,44} <br> 在编译后其实已经被{化ؓtuple。可以通过Name#person.name来访问Name Record的name属性?br><br><span style="FONT-WEIGHT: bold">3.模块的预定义属?/span>Q?br><code>-module(Module).</code>    声明模块名称Q必M文g名相?br><code>-export(Functions).</code>   指定向外界导出的函数列表<br><code>-import(Module,Functions).</code>   引入函数Q引入的函数可以被当作本地定义的函数使用<br><code>-compile(Options).</code>     讄~译选项Q比如export_all<br>-vsn(Vsn).         模块版本Q设|了此项Q可以通过<code>beam_lib:version/1</code> 获取此项信息<br>可以通过-include?include_lib来包含文Ӟ两者的区别是include-lib不能通过l对路径查找文gQ而是在你当前Erlang的lib目录q行查找?br><br><span style="FONT-WEIGHT: bold">4.try表达?/span>Qtry表达式可以与catchl合使用Q比如:<br> <pre>try Expr<br>catch<br> throw:Term -> Term;<br> exit:Reason -> {'EXIT',Reason}<br> error:Reason -> {'EXIT',{Reason,erlang:get_stacktrace()}}<br>end<br><br>不仅如此Qtryq可以与afterl合使用Q类似java中的try..finallyQ用于进行清除作用,比如Q?br>termize_file(Name) -><br>{ok,F} = file:open(Name, [read,binary]),<br>try<br>{ok,Bin} = file:read(F, 1024*1024),<br>binary_to_term(Bin)<br>after<br>file:close(F)<br>end.<br><br><br><span style="FONT-WEIGHT: bold">5.列表推断</span>QList ComprehensionsQ,函数式语aҎ之一QErlang中的语法cMQ?br>[Expr || Qualifier1,...,QualifierN]<br>Expr可以是Q意的表达式,而Qualifier是generator或者filter。还是各举例子说明下?br>1> <strong> [X*2 || X <- [1,2,3]].</strong><br>[2,4,6]<br><br>2> L=[1,2,3,4,5,6,7].<br>[1,2,3,4,5,6,7]<br><br> <pre>3> <span style="FONT-WEIGHT: bold">[X|X<-L,X>=3].</span><br>[3,4,5,6,7]<br><br> <pre>再看几个比较L例子Q来自Programming <a title="" ><u><font color=#000000>Erlang</font></u></a>Q?br>比如<span style="FONT-WEIGHT: bold">快速排?/span>Q?br>-module(qsort).<br>-export([qsort/1]).<br>qsort([])->[];<br>qsort([Pivot|T])-><br>  qsort([X||X<-T,X</pre> <br> <br> <span style="FONT-WEIGHT: bold">6.?/span>Q定义常量或者函数等{,语法如下Q?br> -define(Const, Replacement).<br> -define(Func(Var1,...,VarN), Replacement).<br> <br> 使用的时候在宏名前加个问PQ比?ConstQReplacement插入宏出现的位|。系l预定义了一些宏:<br> <code><span style="FONT-WEIGHT: bold">?MODULE </span> 表示当前模块?br> <br> <span style="FONT-WEIGHT: bold">?MODULE_STRING</span> 同上Q但是以字符串Ş?br> </code><span style="FONT-WEIGHT: bold">?FILE</span> 当前模块的文件名<br> <span style="FONT-WEIGHT: bold">?LINE</span> 调用的当前代码行?br> <span style="FONT-WEIGHT: bold">?MACHINE</span> 机器?br> <br> Erlang的宏与C语言的宏很相|同样有宏指示W,包括Q?br> <dl><dt><code>-undef(Macro).</code> <dd>取消宏定?br> <dt><code>-ifdef(Macro).</code> <dd>当宏Macro有定义的时候,执行以下代码<br> <dt><code>-ifndef(Macro).</code> <dd>同上Q反?br> <dt><code>-else.</code> <dd>接在ifdef或者ifndef之后Q表CZ满前者条件时执行以下代码<br> <br> <dt><code>-endif.</code> <dd>ifl止W?/dd></dl>假设?define(Square(X),X*X).用于计算qxQ那??X返回X表达式的字符串Ş式,cMC语言?arg<br> <br> 一个简单的宏例子:<br> <div id="eamgsyo" class=code_title>ruby 代码</div> <div id="cgyseka" class=dp-highlighter> <div id="wysuoum" class=bar> </div> <ol class=dp-rb> <li id="myauwcc" class=alt><span><span>-</span><span id="gismgmu" class=keyword><strong><font color=#7f0055>module</font></strong></span><span>(macros_demo).  </span></span> <li id="scwikgo" class=""><span>-ifdef(debug).  </span> <li id="sueycig" class=alt><span>-define(LOG(X), io<span id="giugigw" class=symbol>:format</span><span>(</span><span id="qsugmiy" class=string><font color=#0000ff>"{~p,~p}: ~p~n"</font></span><span>, [?MODULE,?LINE,X])).  </span></span> <li id="kugikio" class=""><span>-<span id="iimgqoe" class=keyword><strong><font color=#7f0055>else</font></strong></span><span>.  </span></span> <li id="eoscwus" class=alt><span>-define(LOG(X), <span id="eicugme" class=keyword><strong><font color=#7f0055>true</font></strong></span><span>).  </span></span> <li id="kmyqcki" class=""><span>-endif.  </span> <li id="eokuomc" class=alt><span>-define(Square(X),X*X).  </span> <li id="qamogyu" class=""><span>-compile(export_all).  </span> <li id="amgqkqi" class=alt><span>test()->  </span> <li id="mqimgwk" class=""><span>    A=3,  </span> <li id="wyiummc" class=alt><span>    ?LOG(A),  </span> <li id="eycmyoc" class=""><span>    B=?Square(A),  </span> <li id="coqkmmk" class=alt><span>    io<span id="eoikweu" class=symbol>:format</span><span>(</span><span id="suyimaa" class=string><font color=#0000ff>"square(~w) is ~w~n"</font></span><span>,[A,B]).  </span></span> </li> </ol> </div> <br> 当编译时不开启debug选项的时候:<br> 17> c(macros_demo).<br> {ok,macros_demo}<br> 18> macros_demo:test().<br> square(3) is 9<br> <br> 当编译时开启debug之后Q?br> <br> 19> c(macros_demo,{d,debug}).<br> {ok,macros_demo}<br> 20> macros_demo:test().<br> <span style="FONT-WEIGHT: bold">{macros_demo,11}: 3</span><br> square(3) is 9<br> ok<br> <br> 可以看到LOG的输ZQ行数、模块名以及参数<br> <br> 7?span style="FONT-WEIGHT: bold">Process Dictionary</span>Q每个进E都有自qprocess dictionaryQ用于存储这个进E内的全局变量Q可以通过下列<br> BIFs操作Q?br> put(Key, Value)<br> get(Key)<br> get()<br> get_keys(Value)<br> erase(Key)<br> erase()<br> <br> <span style="FONT-WEIGHT: bold">8、关于分布式~程</span>Q需要补充的几点<br> 1Q节点之间的q接默认是transitiveQ也是当节点Aq接了节点BQ节点Bq接了节点CQ那么节点A也与节点C互相q接<br> 可以通过启动节点时指定参?connect_all false来取消默认行?br> <br> 2Q隐藏节点,某些情况下,你希望连接一个节点而不去连接其他节点,你可以通过在节点启动时指定-hidden选项<br> 来启动一个hidden node。在此情况下Q通过nodes()查看所有连接的节点不会出现隐藏的节点Q想看到隐藏的节?br> 可以通过nodes(hidden)或者nodes(connected)来查看?br> <br> 完整的erl选项如下Q?br> <br> <table cellSpacing=0 cellPadding=2 border=1> <tbody> <tr> <td vAlign=center align=left><code>-connect_all false</code> </td> <td vAlign=center align=left>上面已经解释?</td> </tr> <tr> <td vAlign=center align=left><code>-hidden</code> </td> <td vAlign=center align=left>启动一个hidden node<br></td> </tr> <tr> <td vAlign=center align=left><code>-name Name</code> </td> <td vAlign=center align=left>启动一个系l成点,使用long name. </td> </tr> <tr> <td vAlign=center align=left><code>-setcookie Cookie</code> </td> <td vAlign=center align=left>?code><a title="" ><u><font color=#000000>Erlang</font></u></a>:set_cookie(node(), Cookie)</code>.相同Q设|magic cookie<br></td> </tr> <tr> <td vAlign=center align=left><code>-sname Name</code> </td> <td vAlign=center align=left>启动一个Erlangpȝ作ؓ节点Q用short name <br></td> </tr> </tbody> </table> <br> <br> 注意,<span style="FONT-WEIGHT: bold">short name启动的节Ҏ无法与long name节点通信?/span>?br> <br> <pre><span style="FONT-WEIGHT: bold">.一个小l节Q在Erlang中小于等于是?<表示Q而不是一般语a中的<=语法Q我犯过错误的地方,同样Q不{于都是?P而不?/span><br style="FONT-WEIGHT: bold"><span style="FONT-WEIGHT: bold">!,比如/=?/=?/span><br><br><span style="FONT-WEIGHT: bold">10.and or 和andalso orelse的区?/span><br><br>and和or会计两边的表达式,而andalso和orelse的求值采用短路机Ӟ比如exp1 andalso exp2Q当exp1q回false之后Q就不会L?br>exp2Q而是直接q回falseQ而exp1 and exp2会对exp1和exp2都进行求|or与orelse也类伹{?/pre> </pre> </pre> <img src ="http://www.shnenglu.com/keigoliye/aggbug/95888.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/keigoliye/" target="_blank">暗夜教父</a> 2009-09-11 10:16 <a href="http://www.shnenglu.com/keigoliye/archive/2009/09/11/95888.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Erlang入门Q三Q——分布式~程http://www.shnenglu.com/keigoliye/archive/2009/09/11/95886.html暗夜教父暗夜教父Fri, 11 Sep 2009 02:13:00 GMThttp://www.shnenglu.com/keigoliye/archive/2009/09/11/95886.htmlhttp://www.shnenglu.com/keigoliye/comments/95886.htmlhttp://www.shnenglu.com/keigoliye/archive/2009/09/11/95886.html#Feedback0http://www.shnenglu.com/keigoliye/comments/commentRss/95886.htmlhttp://www.shnenglu.com/keigoliye/services/trackbacks/95886.html一、分布式机制
下列的BIFs是用于分布式~程Q?br>spawn(Node, Mod, Func, Args)
启动q程节点的一个进E?br>
spawn_link(Node, Mod, Func, Args)
启动q程节点的一个进Eƈ创徏q接到该q程

monitor_node(Node, Flag)
如果Flag是true,q个函数调用Q该函数Q的q程可以监控节点Node。如果节点已l舍弃或者ƈ不存在,调用的进E将收到一个{nodedown,Node}的消息。如果Flag是false,监控被关闭

node()
q回我们自己的进Ename

nodes()
q回其他已知的节点name列表

node(Item)
q回原来Item的节点名UͼItem可以是Pid,引用QreferenceQ或者端?port)

disconnect_node(Nodename)
从节点Nodename断开?br>
    节点是分布式Erlang的核心概c在一个分布式Erlang应用中,术语Qterm)节点(nodeQ意味着一个可以加入分布式 transactions的运行系l。通过一个称为net kernal的特D进E,一个独立的Erlangpȝ可以成ؓ一个分布式Erlangpȝ的一部分。当net kernalq程启动的时候,我们U系l是alive的?br>
    与远E节点上的进E进行通信Q与同一节点内的q程通信只有一点不同:
java 代码
  1. {Name, Node} ! Mess.  
  
昄Q需要接收方增加一个参数Node用于指定接受q程所在的节点。节点的name一般是用@隔开的atomcdQ比如pong@dennisQ表C机名ؓdennis上的pong节点。通过执行:
java 代码
  1. erl -sname pong  

在执行的计机中创Z个节点pong。ؓ了运行下面的例子Q你可能需要两台计机Q如果只有一収ͼ只要同时开两个Erlangpȝq以不同的节点名U运行也可以?br>
二、一些例子?br>    q个例子完全来自上面提到的翻译的q接Q关于分布式~程的章节。我增加了截囑֒说明?br>首先是代码:
java 代码
 
  1. -module(tut17).  
  2.   
  3. -export([start_ping/1, start_pong/0,  ping/2, pong/0]).  
  4.   
  5. ping(0, Pong_Node) ->  
  6.     {pong, Pong_Node} ! finished,  
  7.     io:format("ping finished~n", []);  
  8.   
  9. ping(N, Pong_Node) ->  
  10.     {pong, Pong_Node} ! {ping, self()},  
  11.     receive  
  12.         pong ->  
  13.             io:format("Ping received pong~n", [])  
  14.     end,  
  15.     ping(N - 1, Pong_Node).  
  16.   
  17. pong() ->  
  18.     receive  
  19.         finished ->  
  20.             io:format("Pong finished~n", []);  
  21.         {ping, Ping_PID} ->  
  22.             io:format("Pong received ping~n", []),  
  23.             Ping_PID ! pong,  
  24.             pong()  
  25.     end.  
  26.   
  27. start_pong() ->  
  28.     register(pong, spawn(tut17, pong, [])).  
  29.   
  30. start_ping(Pong_Node) ->  
  31.     spawn(tut17, ping, [3, Pong_Node]).  

    代码是创Z个相互通信的进E,怺发送消息ƈ通过io昄在屏q上Q本来是一个单一pȝ的例子,现在我们让两个进E运行在不同的两个节点上。注?start_pingҎQ创建的q程调用pingҎQpingҎ有两个参敎ͼ一个是发送消息的ơ数Q一个就是远E节点的name了,也就是我们将?创徏的进Epong的所在节炏Vstart_pong创徏一个调用函数pong的进E,q注册ؓ名字pongQ因此在pingҎ中可以直接发送消息给 pong)?br>    我是在windows机器上测试,首先打开两个cmdH口Qƈcd到Erlang的安装目录下的bin目录Q比如C:\Program Files\erl5.5.3\bin,上面的E序存ؓtut17.erlQƈ拯到同一个目录下。我们将创徏两个节点Q一个叫 ping@dennis,一个叫pong@dennis,其中dennis是我的机器名。见下图Q?br>
采用同样的命?br>
erl 
-sname ping

创徏ping节点。然后在pong节点下执行start_pong()Q?br>

OK,q样在节点pong上启动了pongq程Q然后在ping节点调用start_pingQ传入参数就是pong@dennis
java 代码
 
  1. tut17:start_ping(pong@dennis).  

执行l果如下图:

同样在pong节点上也可以看到Q?br>

    l果如我们预期的那样Q不同节点上的两个进E相互通信如此单。我们给模块tut17增加一个方法,用于启动q程q程Q也是调用spawn(Node,Module,Func,Args)ҎQ?br>
java 代码
 
  1. start(Ping_Node) ->  
  2.     register(pong, spawn(tut17, pong, [])),  
  3.     spawn(Ping_Node, tut17, ping, [3, node()]).  

pongq程启动Ping_Node节点上的q程ping。具体结果不再给出?br>

暗夜教父 2009-09-11 10:13 发表评论
]]>
Erlang入门Q四Q——错误处理和鲁棒?/title><link>http://www.shnenglu.com/keigoliye/archive/2009/09/11/95887.html</link><dc:creator>暗夜教父</dc:creator><author>暗夜教父</author><pubDate>Fri, 11 Sep 2009 02:13:00 GMT</pubDate><guid>http://www.shnenglu.com/keigoliye/archive/2009/09/11/95887.html</guid><wfw:comment>http://www.shnenglu.com/keigoliye/comments/95887.html</wfw:comment><comments>http://www.shnenglu.com/keigoliye/archive/2009/09/11/95887.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/keigoliye/comments/commentRss/95887.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/keigoliye/services/trackbacks/95887.html</trackback:ping><description><![CDATA[  M一门语a都有自己的错误处理机ӞErlang也不例外Q语法错误编译器可以帮你指出Q而逻辑错误和运行时错误只有靠E序员利用Erlang提供的机制来妥善处理Q放|程序的崩溃?br>    Erlang的机制有Q?br>1)监控某个表达式的执行<br>2Q监控其他进E的行ؓ<br>3Q捕捉未定义函数执行错误{?br><br><span style="FONT-WEIGHT: bold">一、catch和throw语句</span><br>    调用某个会生错误的表达式会D调用q程的非正常退出,比如错误的模式匹配(2=3Q,q种情况下可以用catch语句Q?br>                                      <span style="COLOR: rgb(0,0,0)">catch expression</span><br>    试看一个例子,一个函数fooQ?br><br> <div id="mgiuguu" class=code_title>java 代码</div> <div id="gskoiww" class=dp-highlighter> <div id="acmoaqw" class=bar> </div> <ol class=dp-j> <li id="iuoqciy" class=alt><span><span>foo(</span><span id="wgkuowe" class=number>1</span><span>) ->  </span></span> <li id="keoacky" class=""><span>hello;  </span> <li id="miamgwe" class=alt><span>foo(<span id="ieeqayo" class=number>2</span><span>) ->  </span></span> <li id="qssmqee" class=""><span><span id="kmiscci" class=keyword><strong><font color=#7f0055>throw</font></strong></span><span>({myerror, abc});  </span></span> <li id="kakmoow" class=alt><span>foo(<span id="ycwoiyg" class=number>3</span><span>) ->  </span></span> <li id="qkwycay" class=""><span>tuple_to_list(a);  </span> <li id="mwqsusi" class=alt><span>foo(<span id="mgkmwcc" class=number>4</span><span>) ->  </span></span> <li id="mqkuguk" class=""><span>exit({myExit, <span id="qcoyaqy" class=number>222</span><span>}).  </span></span> </li> </ol> </div> <br>当没有用catch的时候,假设有一个标识符为Pid的进E调用函数fooQ在一个模块中Q,那么Q?br>foo(1) - q回hello<br>foo(2) - 语句throw({myerror, abc})执行Q因为我们没有在一个catch中调用foo(2),因此q程Pid因为错误而终止?br><br>foo(3) - tuple_to_list一个元l{化ؓ列表Q因为a不是元组Q因此进EPid同样因ؓ错误而终?br><br>foo(4) - 因ؓ没有使用catchQ因此foo(4)调用了exit函数ɘq程Pidl止Q{myExit, 222} 参数用于说明退出的原因?br><br>foo(5) - q程Pid因为foo(5)的调用而终止,因ؓ没有和foo(5)匚w的函数foo/1?br><br>    让我们看看用catch之后是什么样Q?br> <div id="yiuegoe" class=code_title>java 代码</div> <div id="swoimuk" class=dp-highlighter> <div id="eqseouc" class=bar> </div> <ol class=dp-j> <li id="gkwyaqe" class=alt><span><span>demo(X) ->  </span></span> <li id="gsegkig" class=""><span><span id="kogkuka" class=keyword><strong><font color=#7f0055>case</font></strong></span><span> </span><span id="mgsosqy" class=keyword><strong><font color=#7f0055>catch</font></strong></span><span> foo(X) of  </span></span> <li id="eqcugmc" class=alt><span>  {myerror, Args} ->  </span> <li id="ceoqcai" class=""><span>       {user_error, Args};  </span> <li id="uoqiekq" class=alt><span>  {'EXIT', What} ->  </span> <li id="moikecs" class=""><span>       {caught_error, What};  </span> <li id="ikegiyw" class=alt><span>  Other ->  </span> <li id="uoqseeu" class=""><span>       Other  </span> <li id="oqimmka" class=alt><span>end.  </span> </li> </ol> </div> <br>再看看结果,<br>demo(1) - 没有错误发生Q因此catch语句返回表辑ּl果hello<br>demo(2) - foo(2)抛出错误{myerror, abc}Q被catchq回Q因此将q回{user_error,abc}<br><br>demo(3) - foo(3)执行p|Q因为参数错误,因此catchq回{'EXIT',badarg'},最后返回{caught_error,badarg}<br><br>demo(4) - q回{caught_error,{myexit,222}}<br>demo(5) - q回{caught_error,function_clause}<br><br>    使用catch和throw可以可能生错误的代码包装hQthrow可以用于N归的退出等{。Erlang是和scheme一栯行尾递归优化的,它们都没有显式的q代l构Q比如for循环Q?br><br><span style="FONT-WEIGHT: bold">二、进E的l止</span><br>    在进E中调用exit的BIFs可以显式地l止q程Qexit(normal)表示正常l止Qexit(Reason)通过Reasonl出非正常终止的原因。进E的l止也完全有可能是因行时错误引v的?br><br><span style="FONT-WEIGHT: bold">三、连接的q程</span><br>    q程之间的连接是双向的,也就是说q程A打开一个连接到B,也意味着有一个从B到A的连接。当q程l止的时候,有一个EXIT信号发l所有与它连接的q程。信L格式如下Q?br>               {'EXIT', Exiting_Process_Id, Reason} <br>Exiting_Process_Id 是指l止的进E标记符<br>Reason 是进E终止的原因。如果Reason是normalQ接受这个信Lq程的默认行为是忽略q个信号。默认对Exit信号的处理可以被重写Q以允许q程对Exit信号的接受做Z同的反应?br>1.q接q程Q?br>通过link(Pid)Q就可以在调用进E与q程Pid之间建立q接<br>2.取消q接<br>反之通过unlink(Pid)取消q接?<br>3.创立q程q连接:<br>通过spawn_link(Module, Function, ArgumentList)创徏q程q连接,该方法返回新创徏的进EPid<br><br>    通过q程的相互连接,许多的进E可以组l成一个网状结构,EXIT信号Q非normal)从某个进E发出(该进E终止)Q所有与它相q的q程以及与这些进 E相q的其他q程Q都收到这个信号ƈl止Q除非它们实C自定义的EXIT信号处理Ҏ。一个进E链状结构的例子Q?br> <div id="cmyauca" class=code_title>java 代码</div> <div id="mgimwus" class=dp-highlighter> <div id="mgqsmus" class=bar> </div> <ol class=dp-j> <li id="cgasmci" class=alt><span><span>-module(normal).  </span></span> <li id="iamyqqe" class=""><span>-export([start/<span id="gsmysig" class=number>1</span><span>, p1/</span><span id="cegauki" class=number>1</span><span>, test/</span><span id="giceowc" class=number>1</span><span>]).  </span></span> <li id="asmisyw" class=alt><span>start(N) ->  </span> <li id="uqscwck" class=""><span>register(start, spawn_link(normal, p1, [N - <span id="oicoiwo" class=number>1</span><span>])).  </span></span> <li id="kwqacag" class=alt><span> p1(<span id="augqciy" class=number>0</span><span>) ->  </span></span> <li id="wsmoayw" class=""><span>   top1();  </span> <li id="qcuqiyo" class=alt><span> p1(N) ->  </span> <li id="gseykgg" class=""><span>   top(spawn_link(normal, p1, [N - <span id="uoimwms" class=number>1</span><span>]),N).  </span></span> <li id="uoysuaq" class=alt><span>top(Next, N) ->  </span> <li id="smwysqy" class=""><span>receive  </span> <li id="mgqcecs" class=alt><span>X ->  </span> <li id="mawgkyg" class=""><span>Next ! X,  </span> <li id="meismui" class=alt><span>io:format(<span id="ymwyaai" class=string><font color=#0000ff>"Process ~w received ~w~n"</font></span><span>, [N,X]),  </span></span> <li id="kcgykig" class=""><span>top(Next,N)  </span> <li id="yicoyyg" class=alt><span>end.  </span> <li id="wyseoeu" class=""><span>top1() ->  </span> <li id="smyauki" class=alt><span>receive  </span> <li id="mgkuems" class=""><span>stop ->  </span> <li id="wqquock" class=alt><span>io:format(<span id="yikogou" class=string><font color=#0000ff>"Last process now exiting ~n"</font></span><span>, []),  </span></span> <li id="eoisusy" class=""><span>exit(finished);  </span> <li id="cmgqcqi" class=alt><span>X ->  </span> <li id="qsugaoy" class=""><span>io:format(<span id="qkueigw" class=string><font color=#0000ff>"Last process received ~w~n"</font></span><span>, [X]),  </span></span> <li id="iewimsa" class=alt><span>top1()  </span> <li id="iuwgsaq" class=""><span>end.  </span> <li id="yasoggu" class=alt><span>test(Mess) ->  </span> <li id="meqcuks" class=""><span>start ! Mess.  </span> </li> </ol> </div> <br>执行Q?br> <div id="umwasqq" class=code_title>java 代码</div> <div id="yiuoywe" class=dp-highlighter> <div id="ysmwgge" class=bar> </div> <ol class=dp-j> <li id="cgsmoec" class=alt><span><span>> normal:start(</span><span id="eyauymc" class=number>3</span><span>).  </span></span> <li id="eyiuwcu" class=""><span><span id="meqkmca" class=keyword><strong><font color=#7f0055>true</font></strong></span><span>  </span></span> <li id="ueqicas" class=alt><span>> normal:test(<span id="kmoikyg" class=number>123</span><span>).  </span></span> <li id="umgsmui" class=""><span>Process <span id="kegkusi" class=number>2</span><span> received </span><span id="mgsyaqq" class=number>123</span><span>  </span></span> <li id="smgiusi" class=alt><span>Process <span id="skmgkig" class=number>1</span><span> received </span><span id="ueyscsi" class=number>123</span><span>  </span></span> <li id="uyysess" class=""><span>Last process received <span id="scwqkaq" class=number>123</span><span>  </span></span> <li id="ykcyiyw" class=alt><span>  </span> <li id="aceyaqo" class=""><span>> normal:test(stop).  </span> <li id="qkeqkao" class=alt><span>Process <span id="akwyagu" class=number>2</span><span> received stop  </span></span> <li id="qcgqkay" class=""><span>Process <span id="cwgiuii" class=number>1</span><span> received stop  </span></span> <li id="gkwgayo" class=alt><span>Last process now exiting  </span> <li id="uoyumca" class=""><span>stop  </span> </li> </ol> </div> <br><span style="FONT-WEIGHT: bold">四、运行时p|</span><br>    一个运行时错误导致进E的非正常终止,伴随着非正常终止EXIT信号发出给所有连接的q程QEXIT信号中有Reasonq且Reason中包含一个atomcd用于说明错误的原因,常见的原因如下:<br><br><span style="FONT-WEIGHT: bold">badmatch</span> - 匚wp|Q比如一个进E进?=3的匹配,q个q程终止,q发出{'EXIT', From, badmatch}信号l连接的q程<br><br><span style="FONT-WEIGHT: bold">badarg</span>  - ֐思义Q参数错误,比如atom_to_list(123),数字不是atomQ因此将发出{'EXIT', From, badarg}信号l连接进E?br><br><span style="FONT-WEIGHT: bold">case_clause</span> - ~少分支匚wQ比?br>    <br> <div id="smoycqy" class=code_title>java 代码</div> <div id="suoqaso" class=dp-highlighter> <div id="yiccgus" class=bar> </div> <ol class=dp-j> <li id="wwsmwck" class=alt><span><span>M = </span><span id="ysueyuc" class=number>3</span><span>,  </span></span> <li id="uoskeeu" class=""><span><span id="skgyaig" class=keyword><strong><font color=#7f0055>case</font></strong></span><span> M of  </span></span> <li id="uoimomu" class=alt><span>  <span id="amwisqq" class=number>1</span><span> ->  </span></span> <li id="oiuwiom" class=""><span>    yes;  </span> <li id="amsyaqo" class=alt><span>  <span id="cwqicai" class=number>2</span><span> ->  </span></span> <li id="eikwyuk" class=""><span>    no  </span> <li id="eauoygu" class=alt><span>end.  </span> </li> </ol> </div> <br>没有分支3Q因此将发出{'EXIT', From, case_clause}l连接进E?br><br><span style="FONT-WEIGHT: bold">if_clause</span> - 同理Qif语句~少匚w分支<br><br><span style="FONT-WEIGHT: bold">function_clause</span> - ~少匚w的函敎ͼ比如Q?br> <div id="yacoqow" class=code_title>java 代码</div> <div id="smgakqy" class=dp-highlighter> <div id="coskwma" class=bar> </div> <ol class=dp-j> <li id="wqceyem" class=alt><span><span>foo(</span><span id="qkmgkiy" class=number>1</span><span>) ->  </span></span> <li id="wscwqwm" class=""><span>  yes;  </span> <li id="eeyawks" class=alt><span>foo(<span id="oacoqem" class=number>2</span><span>) ->  </span></span> <li id="cmoquay" class=""><span>  no.  </span> </li> </ol> </div> <br>如果我们调用foo(3)Q因为没有匹配的函数Q将发出{'EXIT', From, function_clause} l连接的q程?br><br><span style="FONT-WEIGHT: bold">undef</span> - q程执行一个不存在的函?br><br><span style="FONT-WEIGHT: bold">badarith</span> - 非法的算术运,比如1+foo?br><br><span style="FONT-WEIGHT: bold">timeout_value</span> - 非法的超时时间设|,必须是整数或者infinity<br><br><span style="FONT-WEIGHT: bold">nocatch</span> - 使用了throwQ没有相应的catch去通讯?br><br><span style="FONT-WEIGHT: bold">五、修攚w认的信号接收action</span><br>   当进E接收到EXIT信号Q你可以通过process_flag/2Ҏ来修攚w认的接收行ؓ。执行process_flag(trap_exit, true)讄捕获EXIT信号为真来改变默认行为,也就是将EXIT信号作ؓ一般的q程间通信的信可行接受ƈ处理Qprocess_flag (trap_exit,false)重新开启默认行为?br>   例子Q?br> <div id="wyskoks" class=code_title>java 代码</div> <div id="qsmwywm" class=dp-highlighter> <div id="wauoqwu" class=bar> </div> <ol class=dp-j> <li id="koqkmsi" class=alt><span><span>-module(link_demo).  </span></span> <li id="scgiiyy" class=""><span>-export([start/<span id="amwqcia" class=number>0</span><span>, demo/</span><span id="ikmosyy" class=number>0</span><span>, demonstrate_normal/</span><span id="wqamguk" class=number>0</span><span>, demonstrate_exit/</span><span id="giuwayy" class=number>1</span><span>,  </span></span> <li id="uyimeuc" class=alt><span>demonstrate_error/<span id="mgqseus" class=number>0</span><span>, demonstrate_message/</span><span id="augiaqq" class=number>1</span><span>]).  </span></span> <li id="eyicmck" class=""><span>start() ->  </span> <li id="uwsmgmk" class=alt><span>  register(demo, spawn(link_demo, demo, [])).  </span> <li id="qkceqgc" class=""><span>demo() ->  </span> <li id="wyimoes" class=alt><span>  process_flag(trap_exit, <span id="scwgqoo" class=keyword><strong><font color=#7f0055>true</font></strong></span><span>),  </span></span> <li id="kmoqcki" class=""><span>demo1().  </span> <li id="uoimwck" class=alt><span>  demo1() ->  </span> <li id="yykwous" class=""><span>  receive  </span> <li id="mwycmus" class=alt><span>    {'EXIT', From, normal} ->  </span> <li id="moscwmu" class=""><span>      io:format(<span id="egikmkq" class=string><font color=#0000ff>"Demo process received normal exit from ~w~n"</font></span><span>,[From]),  </span></span> <li id="suyiusg" class=alt><span>     demo1();  </span> <li id="imykesk" class=""><span>    {'EXIT', From, Reason} ->  </span> <li id="guwquai" class=alt><span>      io:format(<span id="occgqyw" class=string><font color=#0000ff>"Demo process received exit signal ~w from ~w~n"</font></span><span>,[Reason, From]),  </span></span> <li id="aeoimay" class=""><span>     demo1();  </span> <li id="ayauouc" class=alt><span>    finished_demo ->  </span> <li id="ocwisqy" class=""><span>      io:format(<span id="micoooc" class=string><font color=#0000ff>"Demo finished ~n"</font></span><span>, []);  </span></span> <li id="yswgsou" class=alt><span>    Other ->  </span> <li id="wueqaqy" class=""><span>      io:format(<span id="aogscka" class=string><font color=#0000ff>"Demo process message ~w~n"</font></span><span>, [Other]),  </span></span> <li id="qguoigw" class=alt><span>     demo1()  </span> <li id="usseqou" class=""><span>  end.  </span> <li id="icmoyyw" class=alt><span>demonstrate_normal() ->  </span> <li id="gmqimsy" class=""><span>  link(whereis(demo)).  </span> <li id="gicoaye" class=alt><span>demonstrate_exit(What) ->  </span> <li id="gsmykyw" class=""><span>  link(whereis(demo)),  </span> <li id="uceosio" class=alt><span>  exit(What).  </span> <li id="oaegaiw" class=""><span>demonstrate_message(What) ->  </span> <li id="uimgiig" class=alt><span>  demo ! What.  </span> <li id="uiamymc" class=""><span>demonstrate_error() ->  </span> <li id="ekwakai" class=alt><span>  link(whereis(demo)),  </span> <li id="miewyqw" class=""><span>  <span id="sqseomu" class=number>1</span><span> = </span><span id="soqseuc" class=number>2</span><span>.  </span></span> <li id="koqcoek" class=alt><span>   </span> </li> </ol> </div> <br>    创徏的进E执行demoҎQdemoҎ中设|了trap_exit为true,因此Q在receive中可以像对待一般的信息一样处理EXIT信号Q这个程序是很简单了Q测试看看:<br> <div id="sgacocc" class=code_title>java 代码</div> <div id="iokkmuk" class=dp-highlighter> <div id="cgaueci" class=bar> </div> <ol class=dp-j> <li id="aceqaaq" class=alt><span><span>> link_demo:start().  </span></span> <li id="scugaow" class=""><span><span id="giumiwe" class=keyword><strong><font color=#7f0055>true</font></strong></span><span>  </span></span> <li id="uwqueus" class=alt><span>> link_demo:demonstrate_normal().  </span> <li id="akuwsge" class=""><span><span id="osegiqw" class=keyword><strong><font color=#7f0055>true</font></strong></span><span>  </span></span> <li id="wquegou" class=alt><span>Demo process received normal exit from <<span id="wqmwegg" class=number>0.13</span><span>.</span><span id="eoskwmm" class=number>1</span><span>>  </span></span> <li id="kwqqkss" class=""><span>> link_demo:demonstrate_exit(hello).  </span> <li id="eqsuguu" class=alt><span>Demo process received exit signal hello from <<span id="cwgkuks" class=number>0.14</span><span>.</span><span id="moqamka" class=number>1</span><span>>  </span></span> <li id="yikuwec" class=""><span>** exited: hello **  </span> <li id="oasogge" class=alt><span>  </span> <li id="mqiewmk" class=""><span>> link_demo:demonstrate_exit(normal).  </span> <li id="ueycmka" class=alt><span>Demo process received normal exit from <<span id="aeyicki" class=number>0.13</span><span>.</span><span id="yskoywu" class=number>1</span><span>>  </span></span> <li id="umiscka" class=""><span>** exited: normal **  </span> <li id="umgsuaa" class=alt><span>  </span> <li id="gskgyoe" class=""><span>> link_demo:demonstrate_error().  </span> <li id="woeyaay" class=alt><span>!!! Error in process <<span id="aeyauia" class=number>0.17</span><span>.</span><span id="mqammec" class=number>1</span><span>> in function  </span></span> <li id="uyskwms" class=""><span>!!! link_demo:demonstrate_error()  </span> <li id="mwakesi" class=alt><span>!!! reason badmatch  </span> <li id="egamyuc" class=""><span>** exited: badmatch **  </span> <li id="wsumqom" class=alt><span>Demo process received exit signal badmatch from <<span id="oakoygu" class=number>0.17</span><span>.</span><span id="wqacouu" class=number>1</span><span>>  </span></span> </li> </ol> </div> <br><span style="FONT-WEIGHT: bold">六、未定义函数和未注册名字</span><br>1.当调用一个未定义的函数时QMod:Func(Arg0,...,ArgN)Q这个调用将被{为:<br>error_handler:undefined_function(Mod, Func, [Arg0,...,ArgN]) <br>其中的error_handler模块是系l自带的错误处理模块<br><br>2.当给一个未注册的进E名发送消息时Q调用将被{为:<br>error_handler:unregistered_name(Name,Pid,Message) <br><br>3.如果不用系l自带的error_handlerQ可以通过process_flag(error_handler, MyMod) 讄自己的错误处理模块?br><br><span style="FONT-WEIGHT: bold">七、Catch Vs. Trapping Exits</span><br>q两者的区别在于应用场景不同QTrapping Exits应用于当接收到其他进E发送的EXIT信号Ӟ而catch仅用于表辑ּ的执行?br><br>W?章介l了如何利用错误处理机制L造一个健壮的pȝQ用了几个例子,我将8.2节的例子完整写了下,q添加客Lq程用于试Q?br> <div id="gqaeywc" class=code_title>java 代码</div> <div id="qseoigo" class=dp-highlighter> <div id="wacmoek" class=bar> </div> <ol class=dp-j> <li id="seqcmks" class=alt><span><span>-module(allocator).  </span></span> <li id="yswyioe" class=""><span>-export([start/<span id="cmgqcai" class=number>1</span><span>,server/</span><span id="oqaugwk" class=number>2</span><span>,allocate/</span><span id="uoqskki" class=number>0</span><span>,free/</span><span id="cyauwca" class=number>1</span><span>,start_client/</span><span id="iacmyww" class=number>0</span><span>,loop/</span><span id="keikuks" class=number>0</span><span>]).  </span></span> <li id="oauwiww" class=alt><span>start(Resources) ->  </span> <li id="cyqswmk" class=""><span>   Pid = spawn(allocator, server, [Resources,[]]),  </span> <li id="qcwysqo" class=alt><span>register(resource_alloc, Pid).  </span> <li id="wgkeoek" class=""><span>%函数接口  </span> <li id="umgkmcs" class=alt><span>allocate() ->  </span> <li id="gkmgaoe" class=""><span>   request(alloc).  </span> <li id="gameawm" class=alt><span>free(Resource) ->  </span> <li id="ogkuomc" class=""><span>  request({free,Resource}).  </span> <li id="qmoqksq" class=alt><span>request(Request) ->  </span> <li id="oykmigm" class=""><span>  resource_alloc ! {self(),Request},  </span> <li id="wimwgoe" class=alt><span>  receive  </span> <li id="gaacges" class=""><span>    {resource_alloc, error} ->  </span> <li id="wgweweu" class=alt><span>      exit(bad_allocation); % exit added here  </span> <li id="mqicomc" class=""><span>    {resource_alloc, Reply} ->  </span> <li id="gkuoaqe" class=alt><span>      Reply  </span> <li id="wiscomc" class=""><span> end.  </span> <li id="gikuweu" class=alt><span>% The server.  </span> <li id="yamgqeu" class=""><span>server(Free, Allocated) ->  </span> <li id="yycogom" class=alt><span> process_flag(trap_exit, <span id="cgykwca" class=keyword><strong><font color=#7f0055>true</font></strong></span><span>),  </span></span> <li id="yikoiee" class=""><span> receive  </span> <li id="ceicmcc" class=alt><span>   {From,alloc} ->  </span> <li id="miaegmc" class=""><span>         allocate(Free, Allocated, From);  </span> <li id="ueqieaa" class=alt><span>   {From,{free,R}} ->  </span> <li id="qkeyigg" class=""><span>        free(Free, Allocated, From, R);  </span> <li id="scwgiye" class=alt><span>   {'EXIT', From, _ } ->  </span> <li id="yscyiqw" class=""><span>       check(Free, Allocated, From)  </span> <li id="myqcwes" class=alt><span> end.  </span> <li id="qcmoygg" class=""><span>allocate([R|Free], Allocated, From) ->  </span> <li id="ikuosye" class=alt><span>   link(From),  </span> <li id="yacgywe" class=""><span>   io:format(<span id="qcugaqy" class=string><font color=#0000ff>"q接客户端进E~w~n"</font></span><span>,[From]),  </span></span> <li id="uwiuouc" class=alt><span>   From ! {resource_alloc,{yes,R}},  </span> <li id="ogseywu" class=""><span>   server(Free, [{R,From}|Allocated]);  </span> <li id="gikeecs" class=alt><span>allocate([], Allocated, From) ->  </span> <li id="wwaceka" class=""><span>   From ! {resource_alloc,no},  </span> <li id="smoqkyy" class=alt><span>   server([], Allocated).  </span> <li id="egkkmmc" class=""><span>free(Free, Allocated, From, R) ->  </span> <li id="ammyiiy" class=alt><span>  <span id="ceykuka" class=keyword><strong><font color=#7f0055>case</font></strong></span><span> lists:member({R,From}, Allocated) of  </span></span> <li id="auwqiag" class=""><span>   <span id="yimwqom" class=keyword><strong><font color=#7f0055>true</font></strong></span><span> ->  </span></span> <li id="scoisig" class=alt><span>              From ! {resource_alloc,ok},  </span> <li id="qkwyiqo" class=""><span>              Allocated1 = lists:delete({R, From}, Allocated),  </span> <li id="cwgauaq" class=alt><span>              <span id="mmokeua" class=keyword><strong><font color=#7f0055>case</font></strong></span><span> lists:keysearch(From,</span><span id="gssoygu" class=number>2</span><span>,Allocated1) of  </span></span> <li id="aueqaiw" class=""><span>                     <span id="ikwgqgy" class=keyword><strong><font color=#7f0055>false</font></strong></span><span>->  </span></span> <li id="kuosuky" class=alt><span>                            unlink(From),  </span> <li id="moskwma" class=""><span>                        io:format(<span id="kmgqmcy" class=string><font color=#0000ff>"从进E~w断开~n"</font></span><span>,[From]);  </span></span> <li id="ycegiyo" class=alt><span>                     _->  </span> <li id="moyceua" class=""><span>                            <span id="giseyou" class=keyword><strong><font color=#7f0055>true</font></strong></span><span>  </span></span> <li id="ooawyew" class=alt><span>              end,  </span> <li id="uwyakii" class=""><span>             server([R|Free],Allocated1);  </span> <li id="gkuosiy" class=alt><span>   <span id="ueycuks" class=keyword><strong><font color=#7f0055>false</font></strong></span><span> ->  </span></span> <li id="owacmck" class=""><span>           From ! {resource_alloc,error},  </span> <li id="ykcoqgm" class=alt><span>         server(Free, Allocated)  </span> <li id="eeiaeks" class=""><span> end.  </span> <li id="vnntblz" class=alt><span>  </span> <li id="jzhhfdn" class=""><span>check(Free, Allocated, From) ->  </span> <li id="hnnrxdf" class=alt><span>   <span id="551p553" class=keyword><strong><font color=#7f0055>case</font></strong></span><span> lists:keysearch(From, </span><span id="jrr3l3n" class=number>2</span><span>, Allocated) of  </span></span> <li id="pzhb5j3" class=""><span>         <span id="h555d5t" class=keyword><strong><font color=#7f0055>false</font></strong></span><span> ->  </span></span> <li id="5flrnv1" class=alt><span>           server(Free, Allocated);  </span> <li id="jhbvn3j" class=""><span>        {value, {R, From}} ->  </span> <li id="xpj3n5f" class=alt><span>           check([R|Free],  </span> <li id="rtnrt3z" class=""><span>           lists:delete({R, From}, Allocated), From)  </span> <li id="tl5nrjd" class=alt><span>end.  </span> <li id="txbn5xz" class=""><span>start_client()->  </span> <li id="5n5ztl5" class=alt><span>    Pid2=spawn(allocator,loop,[]),  </span> <li id="5bpj5hp" class=""><span>    register(client, Pid2).  </span> <li id="55rdfn5" class=alt><span>loop()->  </span> <li id="j3zh1f3" class=""><span>    receive  </span> <li id="335tnvx" class=alt><span>        allocate->  </span> <li id="l5l5xhr" class=""><span>            allocate(),  </span> <li id="5t1lnnd" class=alt><span>            loop();  </span> <li id="xpt5pfl" class=""><span>        {free,Resource}->  </span> <li id="pz3d3vd" class=alt><span>            free(Resource),  </span> <li id="z5bpz3j" class=""><span>            loop();  </span> <li id="z55xltr" class=alt><span>        stop->  </span> <li id="5pvp5dl" class=""><span>            <span id="5jb3ddr" class=keyword><strong><font color=#7f0055>true</font></strong></span><span>;  </span></span> <li id="535b5t5" class=alt><span>        _->  </span> <li id="33f5hf5" class=""><span>            loop()  </span> <li id="btrd1br" class=alt><span>    end.  </span> <li id="335jft5" class=""><span>      </span> </li> </ol> </div> <br>回家了,有空再详l说明下q个例子吧。执行:<br> <div id="df5t51p" class=code_title>java 代码</div> <div id="3tn5hhd" class=dp-highlighter> <div id="fztfjjf" class=bar> </div> <ol class=dp-j> <li id="35fv55f" class=alt><span><span id="tv355hh" class=number>1</span><span>> c(allocator).  </span></span> <li id="lvh35hx" class=""><span>{ok,allocator}  </span> <li id="fpr5hnf" class=alt><span><span id="5npr1d1" class=number>2</span><span>> allocator:start([</span><span id="npjv3lr" class=number>1</span><span>,</span><span id="511xjhf" class=number>2</span><span>,</span><span id="vfxr3z5" class=number>3</span><span>,</span><span id="n55v5lr" class=number>4</span><span>,</span><span id="p5rnrr3" class=number>5</span><span>,</span><span id="5dfhv5n" class=number>6</span><span>]).  </span></span> <li id="vhzt35l" class=""><span><span id="x5zbpxl" class=keyword><strong><font color=#7f0055>true</font></strong></span><span>  </span></span> <li id="f3hthxd" class=alt><span><span id="zj3hv5f" class=number>3</span><span>> allocator:start_client().  </span></span> <li id="vxpdhhd" class=""><span><span id="dnztfb5" class=keyword><strong><font color=#7f0055>true</font></strong></span><span>  </span></span> <li id="53vzb5l" class=alt><span><span id="l5f5t5v" class=number>4</span><span>> client!allocate  </span></span> <li id="3zt15pf" class=""><span>.  </span> <li id="31dp5x5" class=alt><span>allocateq接客户端进E?lt;<span id="5r5n3r5" class=number>0.37</span><span>.</span><span id="1333z55" class=number>0</span><span>>  </span></span> <li id="15vfrx5" class=""><span>  </span> <li id="vx3t5f5" class=alt><span><span id="511l5fv" class=number>5</span><span>> client!allocate.  </span></span> <li id="5l1n5x1" class=""><span>allocateq接客户端进E?lt;<span id="d535bjx" class=number>0.37</span><span>.</span><span id="1fhj5p5" class=number>0</span><span>>  </span></span> <li id="dfhbfdr" class=alt><span>  </span> <li id="fz5vdr5" class=""><span><span id="515p3bj" class=number>6</span><span>> client!allocate.  </span></span> <li id="x3ztfx3" class=alt><span>allocateq接客户端进E?lt;<span id="jbv3bp5" class=number>0.37</span><span>.</span><span id="nxr3555" class=number>0</span><span>>  </span></span> <li id="5rlp5l5" class=""><span>  </span> <li id="d55d5z5" class=alt><span><span id="btnpjhf" class=number>7</span><span>> allocator:allocate().  </span></span> <li id="nph551r" class=""><span>q接客户端进E?lt;<span id="rj3x131" class=number>0.28</span><span>.</span><span id="51ldpxl" class=number>0</span><span>>  </span></span> <li id="tlf3jrp" class=alt><span>{yes,<span id="5dz51l3" class=number>4</span><span>}  </span></span> <li id="t55fbr1" class=""><span><span id="hb5fd3h" class=number>8</span><span>> client!{free,</span><span id="v3fhd3h" class=number>1</span><span>}.  </span></span> <li id="5bvprhf" class=alt><span>{free,<span id="b5jlpd5" class=number>1</span><span>}  </span></span> <li id="nfrl5t5" class=""><span><span id="bf5d5nf" class=number>9</span><span>> client!{free,</span><span id="l3f5551" class=number>2</span><span>}.  </span></span> <li id="rnpbf5d" class=alt><span>{free,<span id="535pdbz" class=number>2</span><span>}  </span></span> <li id="r3j5h5r" class=""><span><span id="5htvp5j" class=number>10</span><span>> client!allocate.  </span></span> <li id="pb5zd35" class=alt><span>allocateq接客户端进E?lt;<span id="5zj5trx" class=number>0.37</span><span>.</span><span id="3jjdx55" class=number>0</span><span>>  </span></span> <li id="5b5dtpn" class=""><span>  </span> <li id="b3lpjhd" class=alt><span><span id="xzb5x3f" class=number>11</span><span>> client!allocate.  </span></span> <li id="n33555v" class=""><span>allocateq接客户端进E?lt;<span id="335fz55" class=number>0.37</span><span>.</span><span id="5p55hxv" class=number>0</span><span>>  </span></span> <li id="3j5vpfv" class=alt><span>  </span> <li id="x55hrjf" class=""><span><span id="j5jbvl5" class=number>12</span><span>> client!stop.  </span></span> <li id="5b5l55d" class=alt><span>stop  </span> <li id="3r355l5" class=""><span><span id="vfztvtj" class=number>13</span><span>> allocator:allocate().  </span></span> <li id="nhtl3np" class=alt><span>q接客户端进E?lt;<span id="535555b" class=number>0.28</span><span>.</span><span id="3dzdv3n" class=number>0</span><span>>  </span></span> <li id="5xd35zj" class=""><span>{yes,<span id="j5dxzr3" class=number>3</span><span>}  </span></span> <li id="v3n5b5t" class=alt><span><span id="rln5rh5" class=number>14</span><span>> allocator:allocate().  </span></span> <li id="5zjd5t5" class=""><span>q接客户端进E?lt;<span id="lvr3v51" class=number>0.28</span><span>.</span><span id="xzbnpn5" class=number>0</span><span>>  </span></span> <li id="zrbnz3b" class=alt><span>{yes,<span id="5xbtvl5" class=number>2</span><span>}  </span></span> <li id="5b55pdn" class=""><span><span id="zbf53df" class=number>15</span><span>> allocator:allocate().  </span></span> <li id="33zbvdz" class=alt><span>q接客户端进E?lt;<span id="rt3h5dn" class=number>0.28</span><span>.</span><span id="dv3r3pz" class=number>0</span><span>>  </span></span> <li id="t3555dl" class=""><span>{yes,<span id="jtf3bh5" class=number>1</span><span>}  </span></span> <li id="hr5x555" class=alt><span><span id="x35hvjz" class=number>16</span><span>>  </span></span> </li> </ol> </div> <br> <img src ="http://www.shnenglu.com/keigoliye/aggbug/95887.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/keigoliye/" target="_blank">暗夜教父</a> 2009-09-11 10:13 <a href="http://www.shnenglu.com/keigoliye/archive/2009/09/11/95887.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Erlang入门Q二Q—ƈ发编E?/title><link>http://www.shnenglu.com/keigoliye/archive/2009/09/11/95885.html</link><dc:creator>暗夜教父</dc:creator><author>暗夜教父</author><pubDate>Fri, 11 Sep 2009 02:12:00 GMT</pubDate><guid>http://www.shnenglu.com/keigoliye/archive/2009/09/11/95885.html</guid><wfw:comment>http://www.shnenglu.com/keigoliye/comments/95885.html</wfw:comment><comments>http://www.shnenglu.com/keigoliye/archive/2009/09/11/95885.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/keigoliye/comments/commentRss/95885.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/keigoliye/services/trackbacks/95885.html</trackback:ping><description><![CDATA[<div id="vfrlvlz" class=blog_content>    Erlang中的process——进E是轻量U的Qƈ且进E间无共享。查了很多资料,g没h说清楚轻量q程是什么概念,l箋查找中。。。闲话不 提,q入q发~程的世界。本文算是学习笔讎ͼ也可以说是《Concurrent Programming in ERLANG》第五张的简略翻译?<br><span style="FONT-WEIGHT: bold">1.q程的创?/span><br>    q程是一U自包含的、分隔的计算单元Qƈ与其他进Eƈ发运行在pȝ中,在进E间q没有一个承体p,当然Q应用开发者可以设计这样一个承体pR?br>    q程的创Z用如下语法:<br> <div id="5t5vhv1" class=code_title>java 代码</div> <div id="lnh35zx" class=dp-highlighter> <ol class=dp-j> <li id="j33v5bz" class=alt><span><span>Pid = spawn(Module, FunctionName, ArgumentList)  </span></span> </li> </ol> </div> <br>spawn接受三个参数Q模块名Q函数名以及参数列表Qƈq回一个代表创建的q程的标识符QPidQ?br>如果在一个已知进EPid1中执行:<br> <div id="n55vppd" class=code_title>java 代码</div> <div id="bdx3trp" class=dp-highlighter> <ol class=dp-j> <li id="dh3df5r" class=alt><span><span>Pid2 = spawn(Mod, Func, Args)  </span></span> </li> </ol> </div> <br>那么QPid2仅仅能被Pid1可见QErlangpȝ的安全性就构徏在限制进E扩展的基础上?br><br><span style="FONT-WEIGHT: bold">2.q程间通信</span><br>    Erlangq程间的通信只能通过发送消息来实现Q消息的发送?W号Q?br> <div id="xhtdx5l" class=code_title>java 代码</div> <div id="3p5zb5b" class=dp-highlighter> <ol class=dp-j> <li id="fj53555" class=alt><span><span>Pid ! Message  </span></span> </li> </ol> </div> <br>    其中Pid是接受消息的q程标记W,Message是消息。接受方和消息可以是M的有效的Erlangl构Q只要他们的l果q回的是q程标记W和消息?br>    消息的接受是使用receive关键字,语法如下Q?br> <div id="33l5pf5" class=code_title>java 代码</div> <div id="5vjvfdl" class=dp-highlighter> <ol class=dp-j> <li id="3vf55d5" class=alt><span><span>receive  </span></span> <li id="ld5j55l" class=""><span>      Message1 [when Guard1] ->  </span> <li id="vpjdf3t" class=alt><span>          Actions1 ;  </span> <li id="3h5t55z" class=""><span>      Message2 [when Guard2] ->  </span> <li id="pblvp5j" class=alt><span>          Actions2 ;  </span> <li id="n5x3555" class=""><span>  </span> <li id="5b55n15" class=alt><span>end  </span> </li> </ol> </div> <br>    每一个Erlangq程都有一?#8220;邮箱”Q所有发送到q程的消息都按照到达的顺序存储在“邮箱”里,上面所C的消息Message1,Message2Q?当它们与“邮箱”里的消息匚wQƈ且约束(GuardQ通过Q那么相应的ActionN执行,q且receiveq回的是ActionN的最后一条执?语句的结果。Erlang?#8220;邮箱”里的消息匚w是有选择性的Q只有匹配的消息被触发相应的ActionQ而没有匹配的消息仍然保留在“邮箱”里。这 一机制保证了没有消息会d其他消息的到达?br>    消息到达的顺序ƈ不决定消息的优先U,q程轮检?#8220;邮箱”里的消息q行试匚w。消息的优先U别下文再讲?br><br>    如何接受特定q程的消息呢Q答案很单,发送方(sender)也附送在消息当中Q接收方通过模式匚w军_是否接受Q比如:<br> <div id="xjtpr5z" class=code_title>java 代码</div> <div id="5r3fh5v" class=dp-highlighter> <ol class=dp-j> <li id="xhjdpz1" class=alt><span><span>Pid ! {self(),abc}  </span></span> </li> </ol> </div> <br>l进EPid发送消息{self(),abc}Q利用selfq程得到发送方作ؓ消息发送。然后接收方Q?br> <div id="535bvnl" class=code_title>java 代码</div> <div id="53z1b5b" class=dp-highlighter> <ol class=dp-j> <li id="nnhb55b" class=alt><span><span>receive  </span></span> <li id="xh3lhzn" class=""><span>  {Pid1,Msg} ->  </span> <li id="z5j51d5" class=alt><span>  </span> <li id="h35jn5d" class=""><span>end  </span> </li> </ol> </div> <br>通过模式匚w军_只有Pid1q程发送的消息才接受?br><br><span style="FONT-WEIGHT: bold">3.一些例?/span><br>    仅说明下书中计数的进E例?我添加了单注释:<br> <div id="hjl35db" class=code_title>java 代码</div> <div id="53jhrtj" class=dp-highlighter> <div id="53ztvbz" class=bar> </div> <ol class=dp-j> <li id="h55h555" class=alt><span><span>-module(counter).  </span></span> <li id="ttn3ljz" class=""><span>-compile(export_all).  </span> <li id="515x1d5" class=alt><span>% start()Q返回一个新q程Q进E执行函数loop  </span> <li id="v535xv5" class=""><span>start()->spawn(counter, loop,[<span id="5r555fn" class=number>0</span><span>]).  </span></span> <li id="jtxhdrr" class=alt><span>% 调用此操作递增计数  </span> <li id="3x35pdj" class=""><span>increment(Counter)->  </span> <li id="l3n5pfd" class=alt><span>    Counter!increament.  </span> <li id="5fj55zf" class=""><span>% q回当前计数?nbsp; </span> <li id="5tjldd3" class=alt><span>value(Counter)->  </span> <li id="nz555j5" class=""><span>    Counter!{self(),value},  </span> <li id="b5v55rh" class=alt><span>    receive  </span> <li id="l3dzt3p" class=""><span>        {Counter,Value}->  </span> <li id="3n5hjr3" class=alt><span>            %q回l调用方  </span> <li id="pr3vfvt" class=""><span>            Value  </span> <li id="x5h3515" class=alt><span>        end.  </span> <li id="zj3dn5h" class=""><span>  %停止计数        </span> <li id="j3tzbrp" class=alt><span> stop(Counter)->  </span> <li id="53pbvlh" class=""><span>     Counter!{self(),stop}.  </span> <li id="53dpjx1" class=alt><span> loop(Val)->  </span> <li id="hbvfpnl" class=""><span>     receive  </span> <li id="33bnpn5" class=alt><span>         %接受不同的消息,军_q回l果  </span> <li id="htdxh5d" class=""><span>         increament->  </span> <li id="jlv355f" class=alt><span>             loop(Val+<span id="rblxjzp" class=number>1</span><span>);  </span></span> <li id="d5xznlz" class=""><span>         {From,value}->  </span> <li id="tn353hn" class=alt><span>             From!{self(),Val},  </span> <li id="3f3r3ll" class=""><span>             loop(Val);  </span> <li id="55l51j5" class=alt><span>         stop->  </span> <li id="5lr3vt5" class=""><span>             <span id="3njvnnl" class=keyword><strong><font color=#7f0055>true</font></strong></span><span>;  </span></span> <li id="xpztxd5" class=alt><span>         %不是以上<span id="fjtxphf" class=number>3</span><span>U消息,ql等?nbsp; </span></span> <li id="jb55hx5" class=""><span>         Other->  </span> <li id="5ftdnlj" class=alt><span>             loop(Val)  </span> <li id="vfz5p5r" class=""><span>      end.     </span> <li id="n5fz3hv" class=alt><span>               </span> <li id="hjv5l5v" class=""><span>                          </span> <li id="pjt5x3h" class=alt><span>          </span> </li> </ol> </div> <br>调用方式Q?br><br> <div id="pjl5xvt" class=code_title>java 代码</div> <div id="df5bdv5" class=dp-highlighter> <div id="55jtf5r" class=bar> </div> <ol class=dp-j> <li id="ln33vl5" class=alt><span><span id="55rb55d" class=number>1</span><span>> Counter1=counter:start().  </span></span> <li id="l55t55t" class=""><span><<span id="5j55fvb" class=number>0.30</span><span>.</span><span id="5b53pfl" class=number>0</span><span>>  </span></span> <li id="535zt51" class=alt><span><span id="ppzf5fd" class=number>2</span><span>> counter:value(Counter1).  </span></span> <li id="5vtdn55" class=""><span><span id="5j5hbzp" class=number>0</span><span>  </span></span> <li id="l3vp5v5" class=alt><span><span id="jb3zhdh" class=number>3</span><span>> counter:increment(Counter1).  </span></span> <li id="fprl35b" class=""><span>increament  </span> <li id="3rnhrhx" class=alt><span><span id="zjv5rhp" class=number>4</span><span>> counter:value(Counter1).  </span></span> <li id="v55nzx5" class=""><span><span id="fpznp53" class=number>1</span><span>  </span></span> </li> </ol> </div> <br>Zq程的消息传递机制可以很Ҏ地实现有限状态机QFSMQ,状态用函数表C,而事件就是消息。具体不再展开<br><br><span style="FONT-WEIGHT: bold">4.时讄</span><br>    Erlang中的receive语法可以d一个额外选项QtimeoutQ类|<br> <div id="5p3n35n" class=code_title>java 代码</div> <div id="bfht5b5" class=dp-highlighter> <ol class=dp-j> <li id="5f3d55t" class=alt><span><span>receive  </span></span> <li id="j5b35z5" class=""><span>   Message1 [when Guard1] ->  </span> <li id="5bp55f1" class=alt><span>     Actions1 ;  </span> <li id="5bz555f" class=""><span>   Message2 [when Guard2] ->  </span> <li id="jdn5jrp" class=alt><span>     Actions2 ;  </span> <li id="tn3bvv5" class=""><span>     </span> <li id="3tzlxdb" class=alt><span>   after  </span> <li id="jlx5vbz" class=""><span>      TimeOutExpr ->  </span> <li id="lxpb5td" class=alt><span>         ActionsT  </span> <li id="5p3vztn" class=""><span>end  </span> </li> </ol> </div> <br>after之后的TimeOutExpr表达式返回一个整数timeQ毫U别)Q时间的_E度依赖于Erlang在操作系l或者硬件的实现。如果在time毫秒内,没有一个消息被选中Q超时设|将生效Q也是ActionT执行。time有两个特D|<br>1)<span style="FONT-WEIGHT: bold">infinity</span>(无穷?Qinfinity是一个atomQ指定了时讄永q不会被执行?br>2) <span style="FONT-WEIGHT: bold">0</span>Q超时如果设定ؓ0意味着时讄立L行,但是pȝ首先尝试当?#8220;邮箱”里的消息?br><br>    时的常见几个应用,比如挂v当前q程多少毫秒Q?br> <div id="xvz1frx" class=code_title>java 代码</div> <div id="3b3rj3d" class=dp-highlighter> <div id="l3vpjzh" class=bar> </div> <ol class=dp-j> <li id="dvp3lrh" class=alt><span><span>sleep(Time) ->  </span></span> <li id="bdf3d3z" class=""><span>  receive  </span> <li id="5nr5ndl" class=alt><span>    after Time ->  </span> <li id="bv55hf5" class=""><span>    <span id="5ndzbzf" class=keyword><strong><font color=#7f0055>true</font></strong></span><span>  </span></span> <li id="55vh11p" class=alt><span>end.  </span> </li> </ol> </div> <br>    比如清空q程?#8220;邮箱”,丢弃“邮箱”里的所有消息:<br> <div id="3xjp55z" class=code_title>java 代码</div> <div id="53hl5zx" class=dp-highlighter> <div id="z531dtx" class=bar> </div> <ol class=dp-j> <li id="3b35p55" class=alt><span><span>flush_buffer() ->  </span></span> <li id="dnp1phf" class=""><span>  receive  </span> <li id="5zv35x5" class=alt><span>    AnyMessage ->  </span> <li id="l5f5n55" class=""><span>      flush_buffer()  </span> <li id="5blrbrz" class=alt><span>  after <span id="5jd5zrx" class=number>0</span><span> ->  </span></span> <li id="dx3t35t" class=""><span>    <span id="lfhv3v5" class=keyword><strong><font color=#7f0055>true</font></strong></span><span>  </span></span> <li id="3t5nhx5" class=alt><span>end.  </span> </li> </ol> </div>     <br>    当前进E永q挂P<br> <div id="frjxrrx" class=code_title>java 代码</div> <div id="zbvr555" class=dp-highlighter> <div id="3ln5vvr" class=bar> </div> <ol class=dp-j> <li id="r3hl355" class=alt><span><span>suspend() ->  </span></span> <li id="hrt5dbz" class=""><span>    receive  </span> <li id="331t5jt" class=alt><span>    after  </span> <li id="5zjxv5b" class=""><span>        infinity ->  </span> <li id="5v55xd5" class=alt><span>            <span id="zrvrxx3" class=keyword><strong><font color=#7f0055>true</font></strong></span><span>  </span></span> <li id="n5hrl3f" class=""><span>    end.  </span> </li> </ol> </div> <br><span style="COLOR: rgb(0,0,0)">  </span><span style="COLOR: rgb(0,0,0)">     时也可以应用于实现定时器,比如下面q个例子Q创Z个进E,q个q程在讑֮旉后向自己发送消息:<br> <div id="p555hhn" class=code_title>java 代码</div> <div id="53ln555" class=dp-highlighter> <div id="lnp5tr3" class=bar> </div> <ol class=dp-j> <li id="tdntfl3" class=alt><span><span>-module(timer).  </span></span> <li id="5533n3n" class=""><span>-export([timeout/<span id="dxh3nvd" class=number>2</span><span>,cancel/</span><span id="5f5x55p" class=number>1</span><span>,timer/</span><span id="h5plftj" class=number>3</span><span>]).  </span></span> <li id="btntvl5" class=alt><span>timeout(Time, Alarm) ->  </span> <li id="hrl3h3j" class=""><span>   spawn(timer, timer, [self(),Time,Alarm]).  </span> <li id="p555f55" class=alt><span>cancel(Timer) ->  </span> <li id="d3npjpx" class=""><span>   Timer ! {self(),cancel}.  </span> <li id="pp5d5lb" class=alt><span>timer(Pid, Time, Alarm) ->  </span> <li id="xpr5bj5" class=""><span>   receive  </span> <li id="d3n5hn5" class=alt><span>    {Pid,cancel} ->  </span> <li id="3pzvrfx" class=""><span>       <span id="53nz555" class=keyword><strong><font color=#7f0055>true</font></strong></span><span>  </span></span> <li id="5v5f5lb" class=alt><span>   after Time ->  </span> <li id="pj5rhxd" class=""><span>       Pid ! Alarm  </span> <li id="rbftlbt" class=alt><span>end.  </span> </li> </ol> </div> <br>    <br><span style="FONT-WEIGHT: bold">5、注册进E?/span><br>    Zl进E发送消息,我们需要知道进E的PidQ但是在某些情况下:在一个很大系l里面有很多的全局serversQ或者ؓ了安全考虑需要隐藏进E?Pid。ؓ了达到可以发送消息给一个不知道Pid的进E的目的Q我们提供了注册q程的办法,l进E们注册名字Q这些名字必Latom?br>    基本的调用Ş式:<br> <div id="1tvhrr3" class=code_title>java 代码</div> <div id="ffp3tbj" class=dp-highlighter> <ol class=dp-j> <li id="zlnfz3n" class=alt><span><span>register(Name, Pid)  </span></span> <li id="rjtf3nl" class=""><span>Name与进EPid联系h  </span> <li id="vvh3t3x" class=alt><span>  </span> <li id="5tlx5t1" class=""><span>unregister(Name)  </span> <li id="dnxztb5" class=alt><span>取消Name与相应进E的对应关系?nbsp; </span> <li id="3zrdv55" class=""><span>  </span> <li id="ztfb3dj" class=alt><span>whereis(Name)  </span> <li id="hpd3phv" class=""><span>q回Name所兌的进E的PidQ如果没有进E与之关联,p回atom:undefined  </span> <li id="zjv3h3l" class=alt><span>  </span> <li id="v15dz5t" class=""><span>registered()  </span> <li id="thbdnlj" class=alt><span>q回当前注册的进E的名字列表  </span> </li> </ol> </div> <br><span style="FONT-WEIGHT: bold">6.q程的优先</span><br>讑֮q程的优先可以使用BIFs:<br><span style="FONT-WEIGHT: bold">process_flag(priority, Pri)</span> <br><br>Pri可以是normal、low,默认都是normal<br>优先U高的进E将相对低的执行多一炏V?br><br><span style="FONT-WEIGHT: bold">7.q程l(process group)</span><br>    所有的ERLANGq程都有一个Pid与一个他们共有的UCؓGroup Leader相关联,当一个新的进E被创徏的时候将被加入同一个进E组。最初的pȝq程的Group Leader是它自w,因此它也是所有被创徏q程及子q程的Group Leader。这意味着Erlang的进E被l织ZTreeQ其中的根节点就是第一个被创徏的进E。下面的BIFs被用于操U进E组Q?br><span style="FONT-WEIGHT: bold">group_leader()</span><br>q回执行q程的Group Leader的Pid<br><span style="FONT-WEIGHT: bold">group_leader(Leader, Pid)</span><br>讄q程Pid的Group LeaderE的Leader <br><br><span style="FONT-WEIGHT: bold">8.</span>Erlang的进E模型很ҎL建Client-Server的模型,书中有一节专门讨Zq一点,着重强调了接口的设计以及抽象层ơ的隔离问题Q不译了?/span> </div> <img src ="http://www.shnenglu.com/keigoliye/aggbug/95885.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/keigoliye/" target="_blank">暗夜教父</a> 2009-09-11 10:12 <a href="http://www.shnenglu.com/keigoliye/archive/2009/09/11/95885.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Erlang入门Q一Q?/title><link>http://www.shnenglu.com/keigoliye/archive/2009/09/11/95884.html</link><dc:creator>暗夜教父</dc:creator><author>暗夜教父</author><pubDate>Fri, 11 Sep 2009 02:11:00 GMT</pubDate><guid>http://www.shnenglu.com/keigoliye/archive/2009/09/11/95884.html</guid><wfw:comment>http://www.shnenglu.com/keigoliye/comments/95884.html</wfw:comment><comments>http://www.shnenglu.com/keigoliye/archive/2009/09/11/95884.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/keigoliye/comments/commentRss/95884.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/keigoliye/services/trackbacks/95884.html</trackback:ping><description><![CDATA[<p>   读erlang.org上面的Erlang Course四天教程<br><span style="FONT-WEIGHT: bold">1.</span>数字cdQ需要注意两?br>1QB#Val表示以Bq制存储的数字ValQ比?br></p> <div id="p55tnld" class=code_title>ruby 代码</div> <div id="53b5d55" class=dp-highlighter> <div id="ph3n35d" class=bar> </div> <ol class=dp-rb> <li id="dxplddz" class=alt><span><span>7> 2</span><span id="3j5lnjz" class=comment><font color=#008200>#101.</font></span><span>  </span></span> <li id="pzjdxn5" class=""><span>5  </span> </li> </ol> </div> <p><span style="COLOR: rgb(128,0,0)"><span style="COLOR: rgb(128,0,0)"><span style="COLOR: rgb(0,0,0)"><span style="FONT-WEIGHT: bold">?/span>q制存储?01是10q制??br>2Q?Char表示字符Char的ascii~码Q比?A表示65<br><br><span style="FONT-WEIGHT: bold"></span><span style="FONT-WEIGHT: bold">2.</span>比较难以译的概念——atomQ可以理解成帔RQ它可以包含M字符Q以写字母开_如果不是以小写字母开头或者是字母之外的符P需要用单引号包括v来,比如abc,'AB'<span style="COLOR: rgb(128,0,0)"><span style="FONT-WEIGHT: bold"><br><br><span style="FONT-WEIGHT: bold">3.</span>另一个概念——Tuple,有h译成元l,可以理解成定长数l,是Erlang的基数据l构之一Q?br></p> <div id="d3d5flz" class=code_title>ruby 代码</div> <div id="x5x5p5b" class=dp-highlighter> <ol class=dp-rb> <li id="llprb5v" class=alt><span><span><font color=#000000>8> {1,2,3,4,5}.  </font></span></span> <li id="5l3lhp1" class=""><span><font color=#000000>{1,2,3,4,5}  </font></span> <li id="drxfzj5" class=alt><span><font color=#000000>9> {a,b,c,1,2}.  </font></span> <li id="t5bx3rj" class=""><span><font color=#000000>{a,b,c,1,2}  </font></span> <li id="f5fp3fb" class=alt><span><font color=#000000>10> size({1,2,3,a,b,c}).  </font></span> <li id="5355bzh" class=""><span><font color=#000000>6  </font></span> </li> </ol> </div> <p><br>内置函数size求长度,元组可以嵌套元组或者其他结构。下面所讲的列表也一栗?br><br><span style="FONT-WEIGHT: bold">4.</span>另外一个基数据l构是各个语言都有的listQ列表)Q在[]内以,隔开Q可以动态改变大, <br></p> <div id="bjtphf5" class=code_title>python 代码</div> <div id="tjdxjr3" class=dp-highlighter> <div id="5v55pnt" class=bar> </div> <ol class=dp-py> <li id="b5jlf5p" class=alt><span><span><font color=#000000>[123, xyz]  </font></span></span> <li id="t35t5pn" class=""><span><font color=#000000>[123, </font><span id="ld35x55" class=keyword><font color=#7f0055>def</font></span><span><font color=#000000>, abc]  </font></span></span> <li id="5z5r15z" class=alt><span><font color=#000000>[{person, 'Joe', 'Armstrong'},  </font></span> <li id="p5fhdtp" class=""><span><font color=#000000>    {person, 'Robert', 'Virding'},  </font></span> <li id="5j555xt" class=alt><span><font color=#000000>    {person, 'Mike', 'Williams'}  </font></span> <li id="fnr5fn3" class=""><span><font color=#000000>]  </font></span> </li> </ol> </div> <p><br>可以使用内置函数length求列表大。以""包含的ascii字母代表一个列表,里面的元素就是这些字母的ascii|比如"abc"表示列表[97,98,99]?br><br><span style="FONT-WEIGHT: bold">5.</span>通过q两个数据结构可以组合成各种复杂l构Q与Lisp的cons、list演化出各U结构一L奇妙?br><br><span style="FONT-WEIGHT: bold">6.</span>Erlang中变量有两个特点Q?br>1Q变量必M大写字母开?br>2Q变量只能绑定一ơ,或者以一般的说法是只能赋gơ,其实Erlangq没有赋DL概念,=号也是用于验证匹配?br><br><span style="FONT-WEIGHT: bold">7.</span>模式匚w——Pattern MatchingQErlang的模式匹配非常强大,看了<strong>buaawhl</strong>的?a ><u><font color=#000000>Erlang语法提要</font></u></a>》的介绍Q模式匹配的功能不仅仅在评中介l的数据l构的拆解,在程序的分派也扮演重要角Ԍ或者说Erlang的控制的{是通过模式匚w来实现的。具体功能参见链接,l出书中拆解列表的例子:<br></p> <div id="b3tjv13" class=code_title>python 代码</div> <div id="fb5n35v" class=dp-highlighter> <ol class=dp-py> <li id="vlxjdl5" class=alt><span><span><font color=#000000>[A,B|C] = [1,2,3,4,5,6,7]  </font></span></span> <li id="5n5t5zh" class=""><span><font color=#000000>     Succeeds - binds A = 1, B = 2,  </font></span> <li id="5j3h5jh" class=alt><span><font color=#000000>     C = [3,4,5,6,7]  </font></span> <li id="tbt5z55" class=""><span><font color=#000000>   </font></span> <li id="rzldxn3" class=alt><span><font color=#000000> [H|T] = [1,2,3,4]  </font></span> <li id="j55rhn3" class=""><span><font color=#000000>     Succeeds - binds H = 1, T = [2,3,4]  </font></span> <li id="v5555px" class=alt><span><font color=#000000>   </font></span> <li id="5ftn5b5" class=""><span><font color=#000000> [H|T] = [abc]  </font></span> <li id="5lpj5x5" class=alt><span><font color=#000000>     Succeeds - binds H = abc, T = []  </font></span> <li id="b5h5b55" class=""><span><font color=#000000>   </font></span> <li id="dd5hnlv" class=alt><span><font color=#000000> [H|T] = []  </font></span> <li id="rpzdvbd" class=""><span><font color=#000000>     Fails  </font></span> </li> </ol> </div> <p><!----><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)"> <br>下面会给出更多模式匹配的例子Q给Z个模块用来计列表等<br><br><span style="FONT-WEIGHT: bold">8.</span>Erlang中函数的定义必须在一个模块内QModuleQ,q且模块和函数的名称都必LatomQ函数的参数可以是Q何的Erlangcd或者数据结构,函数要被调用需要从模块中导出,函数调用的Ş式类|<br>moduleName:funcName(Arg1,Arg2,...).<br>写我们的W一个ErlangE序Qh见hqHello WorldQ?br></p> <div id="x5vhlhf" class=code_title>java 代码</div> <div id="nnznzlj" class=dp-highlighter> <div id="d5p5trp" class=bar> </div> <ol class=dp-j> <li id="tt55vtr" class=alt><span><span>-module(helloWorld).  </span></span> <li id="3h5x5d1" class=""><span>-export([run/<span id="5fddhvl" class=number>1</span><span>]).  </span></span> <li id="fnpj5jj" class=alt><span>run(Name)->  </span> <li id="zx3thfv" class=""><span>    io:format(<span id="nnhbnj3" class=string><font color=#0000ff>"Hello World ~w~n"</font></span><span>,[Name]).  </span></span> </li> </ol> </div> <p><br>存ؓhelloWorld.erlQ在Erlang Shell中执行:<br></p> <div id="h55prh5" class=code_title>java 代码</div> <div id="rhtd5vj" class=dp-highlighter> <div id="5xtvppl" class=bar> </div> <ol class=dp-j> <li id="55dpr5t" class=alt><span><span id="n5dztz3" class=number>2</span><span>> c(helloWorld).  </span></span> <li id="d55rl5n" class=""><span>{ok,helloWorld}  </span> <li id="hxrd5lt" class=alt><span><span id="zfrl331" class=number>3</span><span>> helloWorld:run(dennis).  </span></span> <li id="hnrjlbj" class=""><span>Hello World dennis  </span> <li id="v5xzb53" class=alt><span>ok  </span> </li> </ol> </div> <p><br>打印出来了,现在解释下程序构造,<br></p> <div id="tzlxhfd" class=code_title>java 代码</div> <div id="53j5xd5" class=dp-highlighter> <ol class=dp-j> <li id="fn5zv3n" class=alt><span><span>-module(helloWorld).  </span></span> </li> </ol> </div> <p><br>q一行声明了模块helloWorldQ函数必d义在模块内,q且模块名称必须与源文g名相同?br></p> <div id="lbtnx5l" class=code_title>java 代码</div> <div id="dvvzrpf" class=dp-highlighter> <div id="dd351b5" class=bar> </div> <ol class=dp-j> <li id="l5dnp3j" class=alt><span><span>-export([run/</span><span id="f5df3dr" class=number>1</span><span>]).  </span></span> </li> </ol> </div> <p><br>而这一行声明导出的函数Qrun/1指的是有一个参数的run函数Q因为Erlang允许定义同名的有不同参数的多个函敎ͼ通过指定/1来说明要导出的是哪个函数?br>接下来就是函数定义了Q?br></p> <div id="x35vpv5" class=code_title>java 代码</div> <div id="l5r55pv" class=dp-highlighter> <div id="3njdnl5" class=bar> </div> <ol class=dp-j> <li id="pr55ntr" class=alt><span><span>run(Name)->  </span></span> <li id="fl35jp5" class=""><span>    io:format(<span id="nvvz3hv" class=string><font color=#0000ff>"Hello World ~w~n"</font></span><span>,[Name]).  </span></span> </li> </ol> </div> <p><br>大写开头的是变量NameQ调用io模块的formatҎ输出Q~w可以理解成占位符Q将被实际Name取代Q~n是换行了。注意,函数定义完了要以句号.l束。然后执行c(helloWorld).~译源代码,执行Q?br></p> <div id="f35l15j" class=code_title>java 代码</div> <div id="dj35vt5" class=dp-highlighter> <ol class=dp-j> <li id="j5hld5x" class=alt><span><span>helloWorld:run(dennis);  </span></span> </li> </ol> </div> <p><br><span style="FONT-WEIGHT: bold">9.</span>内置的常用函敎ͼ<br></p> <div id="535bt55" class=code_title>java 代码</div> <div id="551lxvl" class=dp-highlighter> <div id="tj35lrp" class=bar> </div> <ol class=dp-j> <li id="vd55v5x" class=alt><span><span>date()  </span></span> <li id="p5l555x" class=""><span>time()  </span> <li id="55rdfvd" class=alt><span>length([<span id="fv5nx35" class=number>1</span><span>,</span><span id="xxl35d5" class=number>2</span><span>,</span><span id="bj3555t" class=number>3</span><span>,</span><span id="dbx3djh" class=number>4</span><span>,</span><span id="3p55v5h" class=number>5</span><span>])  </span></span> <li id="53f5h1z" class=""><span>size({a,b,c})  </span> <li id="f3t5n5p" class=alt><span>atom_to_list(an_atom)  </span> <li id="5z3n5vt" class=""><span>list_to_tuple([<span id="v3j3drp" class=number>1</span><span>,</span><span id="vvrdntj" class=number>2</span><span>,</span><span id="ntnxjpx" class=number>3</span><span>,</span><span id="55vf5lb" class=number>4</span><span>])  </span></span> <li id="v5llf35" class=alt><span>integer_to_list(<span id="5tpr5x5" class=number>2234</span><span>)  </span></span> <li id="d5rd3tz" class=""><span>tuple_to_list({})  </span> <li id="5hf555n" class=alt><span>hd([<span id="djnhbrf" class=number>1</span><span>,</span><span id="f5x5zfd" class=number>2</span><span>,</span><span id="3b5tnlb" class=number>3</span><span>,</span><span id="tjl55lr" class=number>4</span><span>])  %输出</span><span id="thdn3nd" class=number>1</span><span>Q也是列表的head  </span></span> <li id="xlhjtlr" class=""><span>tl([<span id="jzll3db" class=number>1</span><span>,</span><span id="5x5np35" class=number>2</span><span>,</span><span id="xv3zb51" class=number>3</span><span>,</span><span id="nt5zl5b" class=number>4</span><span>])  %输出[</span><span id="jzlxzhn" class=number>2</span><span>,</span><span id="n5x5p51" class=number>3</span><span>,</span><span id="3zpjt5b" class=number>4</span><span>],也就是列表的tail  </span></span> </li> </ol> </div> <p><br><span style="FONT-WEIGHT: bold">10.</span>常见Shell命oQ?br>1Q?span style="FONT-WEIGHT: bold">h().</span> 用来打印最q的20条历史命?br>2Q?span style="FONT-WEIGHT: bold">b().</span> 查看所有绑定的变量<br>3) <span style="FONT-WEIGHT: bold">f().</span> 取消Q遗忘)所有绑定的变量?br>4) <span style="FONT-WEIGHT: bold">f(Val).</span>  取消指定的绑定变?br>5) <span style="FONT-WEIGHT: bold">e(n).</span>   执行Wn条历史命?br>6) <span style="FONT-WEIGHT: bold">e(-1).</span>  执行上一条shell命o<br><br><span style="FONT-WEIGHT: bold">11.</span>又一个不知道怎么译的概念——Guard。翻译成U束Q呵c用于限制变量的cd和范_比如Q?br></p> <div id="ntf355j" class=code_title>java 代码</div> <div id="5hfr55z" class=dp-highlighter> <div id="bz5lnnj" class=bar> </div> <ol class=dp-j> <li id="b3rrn5d" class=alt><span><span>number(X)    - X 是数?nbsp; </span></span> <li id="d531b55" class=""><span>integer(X)    - X 是整?nbsp; </span> <li id="b53hbtr" class=alt><span><span id="5jn355v" class=keyword><font color=#7f0055>float</font></span><span>(X)    - X 是QҎ  </span></span> <li id="dj3xrrp" class=""><span>atom(X)        - X 是一个atom  </span> <li id="3hrv55l" class=alt><span>tuple(X)    - X 是一个元l?nbsp; </span> <li id="l5z3555" class=""><span>list(X)        - X 是一个列?nbsp; </span> <li id="lz5dxdt" class=alt><span>  </span> <li id="znztv53" class=""><span>length(X) == <span id="3vfr515" class=number>3</span><span>    - X 是一个长度ؓ</span><span id="53f55xv" class=number>3</span><span>的列?nbsp; </span></span> <li id="njvfzzn" class=alt><span>size(X) == <span id="fl5j3z1" class=number>2</span><span>    - X 是一个长度ؓ</span><span id="5dxh55n" class=number>2</span><span>的元l?nbsp; </span></span> <li id="d55jt55" class=""><span>  </span> <li id="bhlvpdt" class=alt><span>X > Y + Z    - X >Y+Z  </span> <li id="nt3hbjp" class=""><span>X == Y        - X 与Y相等  </span> <li id="x5t5f51" class=alt><span>X =:= Y        - X 全等于Y  </span> <li id="d5hnh31" class=""><span>(比如Q?nbsp;<span id="drd551p" class=number>1</span><span> == </span><span id="55rrtj5" class=number>1.0</span><span> 成功  </span></span> <li id="rz33j5z" class=alt><span>           <span id="5fh55zp" class=number>1</span><span> =:= </span><span id="5p5rb51" class=number>1.0</span><span> p|)  </span></span> </li> </ol> </div> <p><br>Z方便比较QErlang规定如下的比较顺序:<br></p> <div id="ntxpbrf" class=code_title>java 代码</div> <div id="z5frdbr" class=dp-highlighter> <ol class=dp-j> <li id="l5z3t5t" class=alt><span><span>number < atom < reference < port < pid < tuple < list  </span></span> </li> </ol> </div> <p><br><br><span style="FONT-WEIGHT: bold">12.</span>忘了介绍apply函数Q这个函数对于熟悉javascript的h来说很亲切,javascript实现mixin得靠它Q它的调用方式如下:<br></p> <pre>apply(Mod, Func, Args),三个参数分别是模块、函C及参数列表,比如调用我们的第一个ErlangE序Q?br> <div id="hd3zbr5" class=code_title>java 代码</div> <div id="znz3ffd" class=dp-highlighter> <ol class=dp-j> <li id="53h5jt5" class=alt><span><span>apply(helloWorld,run,[dennis]).  </span></span></li> </ol> </div> <br><span style="FONT-WEIGHT: bold">13.</span>if和case语句Qif语句的结构如下:<br> <div id="53fzlb1" class=code_title>java 代码</div> <div id="535npnd" class=dp-highlighter> <div id="5zbvfv5" class=bar> </div> <ol class=dp-j> <li id="drd35xd" class=alt><span><span id="z5nr3jf" class=keyword><font color=#7f0055>if</font></span><span>  </span></span> <li id="flphthx" class=""><span>   Guard1 ->  </span> <li id="5bdhzh3" class=alt><span>        Sequence1 ;  </span> <li id="3dfh35b" class=""><span>   Guard2 ->  </span> <li id="53hjvl5" class=alt><span>        Sequence2 ;  </span> <li id="zzzd3pv" class=""><span>...  </span> <li id="xd3bb5v" class=alt><span>end  </span></li> </ol> </div> <br>而case语句的结构如下:<br> <div id="b5hzb3l" class=code_title>java 代码</div> <div id="p5d3fxv" class=dp-highlighter> <div id="3txxbhf" class=bar> </div> <ol class=dp-j> <li id="h5xxr5t" class=alt><span><span id="rf5b355" class=keyword><font color=#7f0055>case</font></span><span> Expr of  </span></span> <li id="j5frbr3" class=""><span>   Pattern1 [when Guard1] -> Seq1;  </span> <li id="ft5z5zx" class=alt><span>   Pattern2 [when Guard2] -> Seq2;  </span> <li id="xlv5tz3" class=""><span>  </span> <li id="lrl3p3j" class=alt><span>   PatternN [when GuardN] -> SeqN  </span> <li id="3nrt5ff" class=""><span>end  </span></li> </ol> </div> </pre> <p>if和case语句都有一个问题,是当没有模式匹配或者Grard都是false的时候会DerrorQ这个问题case可以增加一个类似java中default的:<br></p> <div id="rxrb3jz" class=code_title>java 代码</div> <div id="hpp5djj" class=dp-highlighter> <div id="5r5lf53" class=bar> </div> <ol class=dp-j> <li id="rf5lv35" class=alt><span><span id="rxb5n55" class=keyword><font color=#7f0055>case</font></span><span> Fn of  </span></span> <li id="bhl5f55" class=""><span>  </span> <li id="drdnh51" class=alt><span>   _ ->  </span> <li id="5lvz3d5" class=""><span>   <span id="5jlfjbp" class=keyword><font color=#7f0055>true</font></span><span>  </span></span> <li id="ddvx5x3" class=alt><span>end  </span> </li> </ol> </div> <p><br>通过_指代L的ExprQ返回true,而if可以q样Q?br></p> <div id="d5l3v11" class=code_title>java 代码</div> <div id="5dhzdrp" class=dp-highlighter> <div id="5dhh3x5" class=bar> </div> <ol class=dp-j> <li id="zhrt55r" class=alt><span><span id="nb3hl3p" class=keyword><font color=#7f0055>if</font></span><span>  </span></span> <li id="ntx53f3" class=""><span>    </span> <li id="3zdf3rv" class=alt><span>  <span id="3l3fb5l" class=keyword><font color=#7f0055>true</font></span><span> ->  </span></span> <li id="nt3jt5p" class=""><span>   <span id="jpt555d" class=keyword><font color=#7f0055>true</font></span><span>  </span></span> <li id="5f5rld5" class=alt><span>end  </span> </li> </ol> </div> <p><br>一L道理。case语句另一个需要注意的问题是变量范围Q每个case分支中定义的变量都将默认导出case语句Q也是在case语句l束后可以被引用Q因此一个规则就是每个case分支定义的变量应该一_不然是非法的,~译器会l出警告Q比如:<br></p> <div id="pd5j35t" class=code_title>java 代码</div> <div id="znz5dnd" class=dp-highlighter> <div id="jpjthjp" class=bar> </div> <ol class=dp-j> <li id="j5tlpd5" class=alt><span><span>f(X) ->  </span></span> <li id="hv3bf35" class=""><span><span id="hv555n5" class=keyword><font color=#7f0055>case</font></span><span> g(X) of  </span></span> <li id="jptl355" class=alt><span><span id="tblfxl3" class=keyword><font color=#7f0055>true</font></span><span> -> A = h(X), B = A + </span><span id="ft3pjhn" class=number>7</span><span>;  </span></span> <li id="lzjvpdt" class=""><span><span id="33dvx55" class=keyword><font color=#7f0055>false</font></span><span> -> B = </span><span id="5rl3vhv" class=number>6</span><span>  </span></span> <li id="jx3tx35" class=alt><span>end,  </span> <li id="lrv5555" class=""><span>h(A).  </span> </li> </ol> </div> <p><br>如果执行true分支Q变量A和变量B都被定义Q而如果执行的false分支Q只有变量B被引用,可在case语句执行后,h(A)调用了变量AQ这是不安全的,因ؓ变量A完全可能没有被定义,~译器将l出警告<br><span style="FONT-WEIGHT: bold">variable 'A' unsafe in 'case' (line 10)</span><br><br><br><br><span style="FONT-WEIGHT: bold">14.</span>l出一些稍微复杂的模型匚w例子Q比如用于计数字列表的和、^均倹{长度、查找某元素是否在列表中Q我们把q个模块定义为list:<br></p> <div id="jrb3h3t" class=code_title>java 代码</div> <div id="x5lfznd" class=dp-highlighter> <div id="pd535nh" class=bar> </div> <ol class=dp-j> <li id="3dxz55n" class=alt><span><span>-module(list).  </span></span> <li id="d3tl3jh" class=""><span>-export([average/<span id="pxh5vhd" class=number>1</span><span>,sum/</span><span id="xl5rbjx" class=number>1</span><span>,len/</span><span id="dlvx5p3" class=number>1</span><span>,</span><span id="3fxj33f" class=keyword><font color=#7f0055>double</font></span><span>/</span><span id="33prn3z" class=number>1</span><span>,member/</span><span id="5hzd5r5" class=number>2</span><span>]).  </span></span> <li id="d3j555l" class=alt><span>average(X)->sum(X)/len(X).  </span> <li id="vrlxl3h" class=""><span>sum([H|T]) when number(H)->H+sum(T);  </span> <li id="xtnzlzp" class=alt><span>sum([])-><span id="3t55dzx" class=number>0</span><span>.  </span></span> <li id="xdppfbp" class=""><span>len([_|T])-><span id="53pn51h" class=number>1</span><span>+len(T);  </span></span> <li id="33f5pd5" class=alt><span>len([])-><span id="5dvv5vx" class=number>0</span><span>.  </span></span> <li id="pfpjdtr" class=""><span><span id="tj5nz35" class=keyword><font color=#7f0055>double</font></span><span>([H|T]) -> [</span><span id="fl55fv5" class=number>2</span><span>*H|</span><span id="5v5n55p" class=keyword><font color=#7f0055>double</font></span><span>(T)];  </span></span> <li id="znzb5jh" class=alt><span><span id="rx3rdb3" class=keyword><font color=#7f0055>double</font></span><span>([]) -> [].  </span></span> <li id="5pzd3z5" class=""><span>member(H, [H|_]) -> <span id="5hbdpxt" class=keyword><font color=#7f0055>true</font></span><span>;  </span></span> <li id="dr55nvt" class=alt><span>member(H, [_|T]) -> member(H, T);  </span> <li id="5tfpz3l" class=""><span>member(_, []) -> <span id="lrvfrfd" class=keyword><font color=#7f0055>false</font></span><span>.  </span></span> <li id="fvpzbrx" class=alt><span>                  </span> </li> </ol> </div> <p><br>l细体会Q利用递归来实玎ͼ比较有趣。_用于指代L的变量,当我们只x此处有变量,但ƈ不关心变量的值的时候用。用分号;来说明是同一个函数定义,只是不同的定义分支,通过模式匚w来决定调用哪个函数定义分支?br>另一个例子,计算各种囑Ş的面U,也是评中给出的例子Q?br></p> <div id="3nr3b5j" class=code_title>java 代码</div> <div id="ntx3tzp" class=dp-highlighter> <div id="jx35zh5" class=bar> </div> <ol class=dp-j> <li id="dz5v55n" class=alt><span><span>-module(mathStuff).  </span></span> <li id="zx3jv3n" class=""><span>-export([factorial/<span id="rfzb353" class=number>1</span><span>,area/</span><span id="pdprv3f" class=number>1</span><span>]).  </span></span> <li id="f5vvp3x" class=alt><span>factorial(<span id="dr3ph3b" class=number>0</span><span>)-></span><span id="lz3vht3" class=number>1</span><span>;  </span></span> <li id="3ldpz3b" class=""><span>factorial(N) when N><span id="3v5fh3v" class=number>0</span><span>->N*factorial(N-</span><span id="x5l355b" class=number>1</span><span>).  </span></span> <li id="pvh3xtj" class=alt><span>%计算正方形面U,参数元组的第一个匹配square      </span> <li id="rf3dnx5" class=""><span>area({square, Side}) ->  </span> <li id="3dhjtl5" class=alt><span>    Side * Side;  </span> <li id="drdf5jx" class=""><span>%计算圆的面积Q匹配circle    </span> <li id="bpb3zxd" class=alt><span>area({circle, Radius}) ->  </span> <li id="px3jbtp" class=""><span>   % almost :-)  </span> <li id="5zddxx3" class=alt><span>   <span id="5tdh3d5" class=number>3</span><span> * Radius * Radius;  </span></span> <li id="dr35nvr" class=""><span>%计算三角形的面积Q利用v伦公式,匚wtriangle   </span> <li id="5rbnlz5" class=alt><span>area({triangle, A, B, C}) ->  </span> <li id="lt3vh55" class=""><span>   S = (A + B + C)/<span id="3p35hnf" class=number>2</span><span>,  </span></span> <li id="jrd55pv" class=alt><span>math:sqrt(S*(S-A)*(S-B)*(S-C));  </span> <li id="dz3vh3p" class=""><span>%其他  </span> <li id="dlx5nd3" class=alt><span>area(Other) ->  </span> <li id="rhb3zxd" class=""><span>   {invalid_object, Other}.  </span> </li> </ol> </div> <p><br>执行一下看看:<br></p> <div id="ffpbdjp" class=code_title>java 代码</div> <div id="3rbf33d" class=dp-highlighter> <div id="flfjbbp" class=bar> </div> <ol class=dp-j> <li id="f3f3z3t" class=alt><span><span id="pvhtl5f" class=number>1</span><span>> c(mathStuff).  </span></span> <li id="3bvp355" class=""><span>{ok,mathStuff}  </span> <li id="jp3tvln" class=alt><span><span id="b5p5555" class=number>2</span><span>> mathStuff:area({square,</span><span id="h3f3555" class=number>2</span><span>}).  </span></span> <li id="vdvhbpf" class=""><span><span id="n5pvxvv" class=number>4</span><span>  </span></span> <li id="dtvhzp3" class=alt><span><span id="zxhtvbz" class=number>3</span><span>> mathStuff:area({circle,</span><span id="d3lhrrf" class=number>2</span><span>}).  </span></span> <li id="vdv5z5t" class=""><span><span id="pdn553v" class=number>12</span><span>  </span></span> <li id="5b3t5vl" class=alt><span><span id="bjtf5bp" class=number>4</span><span>> mathStuff:area({triangle,</span><span id="3lp35xv" class=number>2</span><span>,</span><span id="tblv55p" class=number>3</span><span>,</span><span id="pd55hhn" class=number>4</span><span>}).  </span></span> <li id="33f55br" class=""><span><span id="jp3tltb" class=number>2.90474</span><span>  </span></span> <li id="xl3pt35" class=alt><span><span id="rzjvnnj" class=number>5</span><span>> mathStuff:area({other,</span><span id="rrtx335" class=number>2</span><span>,</span><span id="rzrdn3t" class=number>3</span><span>,</span><span id="db3f5pf" class=number>4</span><span>}).  </span></span> <li id="zhrdfnb" class=""><span>{invalid_object,{other,<span id="bzt3pn5" class=number>2</span><span>,</span><span id="3rdf5nb" class=number>3</span><span>,</span><span id="5lnp5n5" class=number>4</span><span>}}  </span></span> </li> </ol> </div> <p><br>Erlang使用%开始单行注释?br></span></span></span></span></span></span></p> <img src ="http://www.shnenglu.com/keigoliye/aggbug/95884.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/keigoliye/" target="_blank">暗夜教父</a> 2009-09-11 10:11 <a href="http://www.shnenglu.com/keigoliye/archive/2009/09/11/95884.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.cs556.cn" target="_blank">ŷպƷþþþ</a>| <a href="http://www.voxj.cn" target="_blank">þҹɫƷAV</a>| <a href="http://www.e-bizcard.cn" target="_blank">þŷƷ</a>| <a href="http://www.sifubaimeng.cn" target="_blank">vĻþ</a>| <a href="http://www.xinashop.cn" target="_blank">ھƷ˾þþþavһ</a>| <a href="http://www.sdmtsk.cn" target="_blank">ݺɫۺþö </a>| <a href="http://www.zfhotel.cn" target="_blank">˾Ʒþۺ</a>| <a href="http://www.lslscy.cn" target="_blank">þ޸ۺ</a>| <a href="http://www.qj119.cn" target="_blank">뾫Ʒþþþ..</a>| <a href="http://www.hljfucai.cn" target="_blank">޹˾þۺ3d</a>| <a href="http://www.antsgogo.cn" target="_blank">ۿƷþ</a>| <a href="http://www.q126.cn" target="_blank">þþƷĻ̾</a>| <a href="http://www.ccguofeng.cn" target="_blank">ɫþþþþۺ</a>| <a href="http://www.xn88.cn" target="_blank">þ96Ʒþþ</a>| <a href="http://www.xiaoneiweb.cn" target="_blank">ݺɫ˾þþƷۺ </a>| <a href="http://www.i501.cn" target="_blank">Ʒþþþþۺձ</a>| <a href="http://www.px2s.cn" target="_blank">鶹Ʒþþһ</a>| <a href="http://www.1webproxy.cn" target="_blank">ƷžžþƵ </a>| <a href="http://www.jrchen.cn" target="_blank">޾Ʒרþþ</a>| <a href="http://www.847888.com.cn" target="_blank">ɫþþ99Ʒ</a>| <a href="http://www.myloveshop.com.cn" target="_blank">wwwþ</a>| <a href="http://www.4527.com.cn" target="_blank">þۺϺݺۺϾþ</a>| <a href="http://www.jj171.cn" target="_blank">ĻƷþ</a>| <a href="http://www.lwtjf.cn" target="_blank">˾Ʒþ</a>| <a href="http://www.gangzheng.net.cn" target="_blank">Ʒþþþ9999</a>| <a href="http://www.945ba.cn" target="_blank">þþƷAVɫ</a>| <a href="http://www.sunwebs.cn" target="_blank">þwww˳ɿƬ</a>| <a href="http://www.mtdo.cn" target="_blank">þ99ȾƷ</a>| <a href="http://www.douyinyutang.cn" target="_blank">պĻþ</a>| <a href="http://www.szmpp.cn" target="_blank">޾ƷþëƬ</a>| <a href="http://www.fzmnls.cn" target="_blank">þþþùƷ۲ӰԺ</a>| <a href="http://www.818wg.cn" target="_blank">ѾþþƷѾѾ</a>| <a href="http://www.f1490.cn" target="_blank">þѹƷһ</a>| <a href="http://www.9kgat.cn" target="_blank">ƷþþþþþþѼ</a>| <a href="http://www.153u.cn" target="_blank">þAVӰ</a>| <a href="http://www.b24193.cn" target="_blank">ҹþþþüŮӰԺ</a>| <a href="http://www.androidfans.com.cn" target="_blank">AŮAVۺϾþþ</a>| <a href="http://www.zjyffm.cn" target="_blank">þۺϾɫۺϾ99</a>| <a href="http://www.mdwmp.com.cn" target="_blank">þøһëƬ</a>| <a href="http://www.sxttzs.cn" target="_blank">ϵרþ</a>| <a href="http://www.sanghuan.cn" target="_blank">þþƷ72</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>