- 浏览: 500058 次
- 性别:
- 来自: 上海
-
文章分类
最新评论
-
hypercube:
markin'
配置D语言编程环境 -
qiezi:
qiezi 写道yangyang_08 写道1 ...
我的编程语言学习经历 -
qiezi:
yangyang_08 写道1、现在如果做并发服务器,楼主选用 ...
我的编程语言学习经历 -
yangyang_08:
1、现在如果做并发服务器,楼主选用什么样的语言架构?2、lua ...
我的编程语言学习经历 -
dearplain:
我也是语言爱好者,不过我一直坚持使用c。
我的编程语言学习经历
考虑到现有的项目使用erlang重写的复杂性和erlang对于某些数据库支持的弱点,想结合erlang的分布式、代码热加载、处理高并发方面的优势,和C++在性能上以及大量现有项目上的优势,实现集群部署。
考察了erlang和C进行交互的几种方式,ports受限于物理服务器分布,port_driver没测试成功,应该也是受限于本机,最后选定C nodes方式。
测试了c server和c client两种方式,感觉如果是server方式,还得用C写一套处理高并发的网络模块,也不方便升级,erlang的优势完全没发挥上,所以选定client方式。
大致的想法是这样的:
* erlang监听一个本地端口和一个对外的端口,本地的用于和c node通讯,对外的通过协议和客户交互。
* c node连接到本地端口后,就在erlang里面注册一个名字,这时候对外的端口上收到的数据就根据这个名字发给c node。
* c node上接收到数据以后就放队列,给线程池去消化,线程池处理完以后就通过端口发回给erlang节点,当然是使用erl_send (问题1)。
* erlang上面当然是由process“阻塞”处理,它收到结果以后,就发回给客户端,这个阻塞当然是假的,也正是利用erlang编程的便利。
* c node升级,只需要另开一个程序,注册另一个名字,比如名字加上版本号,连到erlang节点,再使用热加载把erlang代码更新,就可以在不停机的情况下更新服务器。更新完了再停掉旧版本的c node。
* 增加协议格式等操作都交给erlang了,C node保持不变。
不知道erlang应用于这种项目,上面这种方式是不是最优的?请有经验的朋友指点。
问题1:
erl_send是不是线程安全的?如果不是,我可能要做个发送线程去处理发送队列了。
我遇到的情况也类似。最常见的情况是长函数一大堆,或者因为模块划分不好,导致循环依赖。在这个坛子里,大多数人都认为 c++ 难学难精,但是在我遇到的情况中,好像是反过来,反而好像认为随便一个人都是 c++ 高手,有些重要的关于项目方面的决策也没怎么讨论,随便就交给了一个新手,结果就像 qiezi 说的:“很多C++项目,明显是生手的练习,各种漏洞一大堆”。
呵呵,公司有那么宽松的时间给你? 口水ing 。。。。。。
我经常也有这样的想法,不过公司基本上不会答应。所以只好自己业余时间来试了。
赞一个
原来如此。看到这些协议了:
4.2.1.1 LINK
{1, FromPid, ToPid}
4.2.1.3 EXIT
{3, FromPid, ToPid, Reason}
4.2.1.4 UNLINK
{4, FromPid, ToPid}
4.4.1 MONITOR_P
{19, FromPid, ToProc, Ref}
FromPid = monitoring process
ToProc = monitored process pid or name (atom)
4.4.2 DEMONITOR_P
{20, FromPid, ToProc, Ref}
We include the FromPid just in case we want to trace this.
FromPid = monitoring process
ToProc = monitored process pid or name (atom)
4.4.3 MONITOR_P_EXIT
{21, FromProc, ToPid, Ref, Reason}
FromProc = monitored process pid or name (atom)
ToPid = monitoring process
Reason = exit reason for the monitored process
看样子都是基于Process的,难道monitor_node实际上是用link或monitor_p协议做出来的?不过我看erts/emulator/beam/dist.c里面有个monitor_node_3,但没有以public方式开放出来。
另外,你们公司还是比较人性化啊,做得快,剩下的时间可以自己支配。最担心就是公司见你做得快,很好,再来一个!然后你变成了做得最快,但是最忙的人,呵呵。
我们公司是给自己做软件,作为WEB应用,稳定性比进度重要。通常逻辑也比较简单,只是要从系统架构上考虑任何一个点挂掉以后的备用策略。
----------------------------------------------------------------------------
这个帖子提到的erlang应用,我简单测试了一下还是可行的,简单总结一下用到的知识。
1、分布式结点发送消息注册服务:
{manager, 'a@xxx.xxx.xxx.xxx'} ! {reg_service, auth, self()}
2、监测节点退出:
monitor_node('a@xxx.xxx.xxx.xxx', true)
然后接收:
{nodedown, Node}
3、监测进程退出:
process_flag(trap_exit, true),
link(Pid)
4、远程节点心跳检测:
erl -heart
设置心跳间隔:
erl -heart -env HEART_BEAT_TIMEOUT 30 设置30秒心跳间隔,范围是10-65535秒之间。
有这些应该够用了。如果是C程序,如何发出monitor_node和process_flag/link呢?也可以从erlang节点上检测C节点,不过还是想知道反过来怎么检测。
出现长函数,或者模块划分不清楚,很多时候是由于开发人员没有清晰的分层意识,没有分清楚公用库和胶合代码。有时候有些库是从特定项目中重构出来的。在重构成库的过程中,没有考虑清楚这个库的主体功能,从而把一些胶合代码也被放到了库里面。导致这个库本身就依赖于太多的其他库。当需要使用这个库的时候,令人发狂的事情就开始了。
嗯,对于后台开发,很多复杂的情况,不用单元测试,可能还没那么容易模拟出来。单元测试一般来说,能够比较方便地模拟出自己想要的前提条件。
另外,你们公司还是比较人性化啊,做得快,剩下的时间可以自己支配。最担心就是公司见你做得快,很好,再来一个!然后你变成了做得最快,但是最忙的人,呵呵。
长函数是普遍情况了,呵呵。比较合理的情况,公用库放在外面,项目特定的代码应该只有少于1/5的代码用来把一些库串联起来,而逻辑部分则应该占到1/2或更多,其它都是完成架构不可少的胶合代码。但目前一些项目,几十个文件在一起,只有几个文件是逻辑的,但却不能离开其它文件单独拿来测试。逻辑处理基本上都是长函数,加上没有很好的利用分级日志,排错非常麻烦,服务器又不能经常重启去做调试。
呵呵,公司有那么宽松的时间给你? 口水ing 。。。。。。
我经常也有这样的想法,不过公司基本上不会答应。所以只好自己业余时间来试了。
我刚到这公司时,写代码就是有名的快,一周的任务都是一天之内完成,其实也不是很快,只不过大家都习惯了慢。搞C++的多半都喜欢调试而不喜欢单元测试,我正是使用这一简单的敏捷方式来提高开发效率,可测试的代码通常接口也比较好,重用性也会很好。初期大家都不放心,不过负责的几个项目都是最稳定的,也就没什么疑虑了。这样我每周可以省很多时间,几乎所有的时间都是在写代码或看书。对我来说时间还是充裕的,只不过喜欢的东西太杂太多,每样都搞点皮毛,所以显得也很忙。通常服务器系统写完测试上线还需要监控一段时间,这段时间基本上是不分配任务的,定时上去监控看一下日志就好,一般这些时间有些同事在聊天、下棋什么的(好像公司不反对),我拿这些时间看书或写代码。多点练习也是好的,我刚来时公司有很多各方面的专家,很短一段时间以后,我就发现他们的很多理论是错误的,很多都是在做项目的过程中看过一些文档后就深信不疑,而我喜欢写代码验证,所以一段时间以后我的意见就能成为更有参考价值的。
又跑题了。难怪说:3页之内必跑题,如果没跑肯定是前2页已经跑了。。
跑题也没什么,话题都是扩展的,如果能把一个帖子的各个回帖打标签就好了,连在一起看时也可以知道是怎么跑到这个话题上的,分开看也价值。
我遇到的情况也类似。最常见的情况是长函数一大堆,或者因为模块划分不好,导致循环依赖。在这个坛子里,大多数人都认为 c++ 难学难精,但是在我遇到的情况中,好像是反过来,反而好像认为随便一个人都是 c++ 高手,有些重要的关于项目方面的决策也没怎么讨论,随便就交给了一个新手,结果就像 qiezi 说的:“很多C++项目,明显是生手的练习,各种漏洞一大堆”。
呵呵,公司有那么宽松的时间给你? 口水ing 。。。。。。
我经常也有这样的想法,不过公司基本上不会答应。所以只好自己业余时间来试了。
那估计你们公司没什么希望. 不考虑以后维护性方面的问题. 我自己也挺讨厌想LZ这种所谓的"牛人", 自己随自己喜欢, 那公司的东西做实验, 做烂了就拍拍屁股走人.
python应用这么广,公司大部分人都会,会C++的学python几天就可以上手,而且公司目前大力推广C++配合脚本语言开发业务逻辑,我带个头而已。erlang我还没应用到项目中呢,用的人毕竟是少,很多时候有些项目都是临时性的,解决一时的问题,过渡性方案,要求快速开发,用完就没什么用了,所以我经常会在各个项目里临时救一下火,或者是要快速做一下原型,你不得找个开发效率和运行效率都过得去的东西?另外模块化的开发很容易维护,都是分布式系统,协议兼容就可以了。倒是公司现有的很多C++项目,明显是生手的练习,各种漏洞一大堆,几乎所有的项目都被补过一遍了,可维护性是有,却是很需要维护啊,而且维护的成本也不低。
我在公司基本上所有时间都在写代码,这是唯一爱好,一个项目完了如果有其它可选方案我肯定会试试,或者是其它语言来实现,你经常会看到我说用什么语言做项目,那是因为我完成了现有项目,多出来的时间我做些尝试而已,其他同事完成项目后都在聊天或看网站,我不过是做点不同的事而已。几乎每个项目我都实现过多种可选方案,然后进行比较,再找一下各种方案的差异,当然最后上线的肯定是C++版本的,每种方案都做完了,都是可以上线的版本,上哪个版本正是考虑到以后的维护性问题。你说做实验也可以,至少我没搞砸过一个项目,否则我早被开掉了。关于公司,在不到2年时间里,日浏览量目前已经接近搜狐,你要说没什么希望我也不需要反驳。。。每种公司都有自己的文化氛围,越是成功的公司越会鼓励员工尝试新技术,而不是以各种理由去阻碍。拍拍屁股走人更不是我的风格,我在过去工作过的地方时间都很长,不要拿自己的习惯去猜度别人。
又要成吵架帖了。最后说几句:
1、怀疑别人的人品的话不要说,除非你有证据证明我人品有问题。
2、明确的对别人说你讨厌他这种类型,很明显是一种挑衅行为,版规所不容。
qiezi 是怎么说服公司使用 erlang 的?我对这一点比较好奇
还没说服啊,公司并不看我写代码,项目搞稳定就行了,我已经把一部分用python写了,其它部分则使用了一些第三方库比如log4cxx,同事项目有问题就会看我怎么做,看了也会学着用的。目前有些部分本来就是独立的进程,用配置文件去定义功能,然后组合到新的服务器中,用什么语言实现都没多大差别了,稳定、高效就是唯一追求。
那估计你们公司没什么希望. 不考虑以后维护性方面的问题. 我自己也挺讨厌想LZ这种所谓的"牛人", 自己随自己喜欢, 那公司的东西做实验, 做烂了就拍拍屁股走人.
赫赫,跟我猜测的不大一样,没做过实际测试,原来估计 两个线程的切换和 四个线程的切换,系统在切换上所花的时间应该差别不大,照你实际情况来看,我的估计还是错误的。
看具体情况吧,网游这种计算集中的,数据都从外部主动输入,当然是线程数少比较好,目前很多网游都是单线程跑逻辑。一些中间层服务封装数据库、远程服务调用和事务的,通常IO延时会比较明显,这时候多个线程效果比较好。这2种情况下erlang都是适用的。
可以设置成erlang使用一个线程,C node开3线程,一共4个,在4CPU上运行,目前使用的服务器都是4CPU的,部分高档货8CPU。通常运行时线程数会更多,因为各种IO都会影响,我测试线程数达到十几个才会明显感觉到线程切换的影响,这个数字也和测试的具体业务相关,通常是根据测试情况来配置。
赫赫,跟我猜测的不大一样,没做过实际测试,原来估计 两个线程的切换和 四个线程的切换,系统在切换上所花的时间应该差别不大,照你实际情况来看,我的估计还是错误的。
可以设置成erlang使用一个线程,C node开3线程,一共4个,在4CPU上运行,目前使用的服务器都是4CPU的,部分高档货8CPU。通常运行时线程数会更多,因为各种IO都会影响,我测试线程数达到十几个才会明显感觉到线程切换的影响,这个数字也和测试的具体业务相关,通常是根据测试情况来配置。
还没说服啊,公司并不看我写代码,项目搞稳定就行了,我已经把一部分用python写了,其它部分则使用了一些第三方库比如log4cxx,同事项目有问题就会看我怎么做,看了也会学着用的。目前有些部分本来就是独立的进程,用配置文件去定义功能,然后组合到新的服务器中,用什么语言实现都没多大差别了,稳定、高效就是唯一追求。
qiezi你在实现哪些功能的时候用了python?说说看,我想借鉴你的经验。
运行效率要求不是特别高的地方都可以用,比如日志服务器、文件服务器、大量的压力测试程序、文本处理等。
考察了erlang和C进行交互的几种方式,ports受限于物理服务器分布,port_driver没测试成功,应该也是受限于本机,最后选定C nodes方式。
测试了c server和c client两种方式,感觉如果是server方式,还得用C写一套处理高并发的网络模块,也不方便升级,erlang的优势完全没发挥上,所以选定client方式。
大致的想法是这样的:
* erlang监听一个本地端口和一个对外的端口,本地的用于和c node通讯,对外的通过协议和客户交互。
* c node连接到本地端口后,就在erlang里面注册一个名字,这时候对外的端口上收到的数据就根据这个名字发给c node。
* c node上接收到数据以后就放队列,给线程池去消化,线程池处理完以后就通过端口发回给erlang节点,当然是使用erl_send (问题1)。
* erlang上面当然是由process“阻塞”处理,它收到结果以后,就发回给客户端,这个阻塞当然是假的,也正是利用erlang编程的便利。
* c node升级,只需要另开一个程序,注册另一个名字,比如名字加上版本号,连到erlang节点,再使用热加载把erlang代码更新,就可以在不停机的情况下更新服务器。更新完了再停掉旧版本的c node。
* 增加协议格式等操作都交给erlang了,C node保持不变。
不知道erlang应用于这种项目,上面这种方式是不是最优的?请有经验的朋友指点。
问题1:
erl_send是不是线程安全的?如果不是,我可能要做个发送线程去处理发送队列了。
评论
28 楼
everlasting_188
2008-04-12
iunknown 写道
qiezi 写道
倒是公司现有的很多C++项目,明显是生手的练习,各种漏洞一大堆,几乎所有的项目都被补过一遍了,可维护性是有,却是很需要维护啊,而且维护的成本也不低。
我遇到的情况也类似。最常见的情况是长函数一大堆,或者因为模块划分不好,导致循环依赖。在这个坛子里,大多数人都认为 c++ 难学难精,但是在我遇到的情况中,好像是反过来,反而好像认为随便一个人都是 c++ 高手,有些重要的关于项目方面的决策也没怎么讨论,随便就交给了一个新手,结果就像 qiezi 说的:“很多C++项目,明显是生手的练习,各种漏洞一大堆”。
qiezi 写道
几乎每个项目我都实现过多种可选方案,然后进行比较,再找一下各种方案的差异,当然最后上线的肯定是C++版本的,每种方案都做完了,都是可以上线的版本,上哪个版本正是考虑到以后的维护性问题。
呵呵,公司有那么宽松的时间给你? 口水ing 。。。。。。
我经常也有这样的想法,不过公司基本上不会答应。所以只好自己业余时间来试了。
![](/images/smiles/icon_biggrin.gif)
27 楼
mryufeng
2007-07-31
erl的trace更是强大 erts\emulator\beam\erl_trace.c emulator的实现 还有更cool的 et_viewer 对整个message 的流向更是 尽收眼底, 对分布程序的调试真是太方便了
26 楼
mryufeng
2007-07-31
monitor是 erts\emulator\beam\erl_monitors.c 里面实现的 看下 .h的说明
/**********************************************************************
* Header for monitors and links data structures.
* Monitors are kept in an AVL tree and the data structures for
* the four different types of monitors are like this:
**********************************************************************
* Local monitor by pid/port:
* (Ref is always same in all involved data structures)
**********************************************************************
* Process/Port X Process Y
* +-------------+ +-------------+
* Type: | MON_ORIGIN | | MON_TARGET |
* +-------------+ +-------------+
* Pid: | Pid(Y) | | Pid/Port(X) |
* +-------------+ +-------------+
* Name: | [] | | [] |
* +-------------+ +-------------+
**********************************************************************
* Local monitor by name: (Ref is always same in all involved data structures)
**********************************************************************
* Process X Process Y (name foo)
* +-------------+ +-------------+
* Type: | MON_ORIGIN | | MON_TARGET |
* +-------------+ +-------------+
* Pid: | Pid(Y) | | Pid(X) |
* +-------------+ +-------------+
* Name: | Atom(foo) | | Atom(foo) |
* +-------------+ +-------------+
**********************************************************************
* Remote monitor by pid: (Ref is always same in all involved data structures)
**********************************************************************
* Node A | Node B
* ---------------------------------+----------------------------------
* Process X (@A) Distentry @A Distentry @B Process Y (@B)
* for node B for node A
* +-------------+ +-------------+ +-------------+ +-------------+
* Type: | MON_ORIGIN | | MON_TARGET | | MON_ORIGIN | | MON_TARGET |
* +-------------+ +-------------+ +-------------+ +-------------+
* Pid: | Pid(Y) | | Pid(X) | | Pid(Y) | | Pid(X) |
* +-------------+ +-------------+ +-------------+ +-------------+
* Name: | [] | | [] | | [] | | [] |
* +-------------+ +-------------+ +-------------+ +-------------+
**********************************************************************
* Remote monitor by name: (Ref is always same in all involved data structures)
**********************************************************************
* Node A | Node B
* ---------------------------------+----------------------------------
* Process X (@A) Distentry @A Distentry @B Process Y (@B)
* for node B for node A (name foo)
* +-------------+ +-------------+ +-------------+ +-------------+
* Type: | MON_ORIGIN | | MON_TARGET | | MON_ORIGIN | | MON_TARGET |
* +-------------+ +-------------+ +-------------+ +-------------+
* Pid: | Atom(node B)| | Pid(X) | | Pid(Y) | | Pid(X) |
* +-------------+ +-------------+ +-------------+ +-------------+
* Name: | Atom(foo) | | Atom(foo) | | Atom(foo) | | Atom(foo) |
* +-------------+ +-------------+ +-------------+ +-------------+
* The reason for the node atom in X->pid is that we don't know the actual
* pid of the monitored process on the other node when setting the monitor
* (which is done asyncronously).
**********************************************************************/
/**********************************************************************
* Header for monitors and links data structures.
* Monitors are kept in an AVL tree and the data structures for
* the four different types of monitors are like this:
**********************************************************************
* Local monitor by pid/port:
* (Ref is always same in all involved data structures)
**********************************************************************
* Process/Port X Process Y
* +-------------+ +-------------+
* Type: | MON_ORIGIN | | MON_TARGET |
* +-------------+ +-------------+
* Pid: | Pid(Y) | | Pid/Port(X) |
* +-------------+ +-------------+
* Name: | [] | | [] |
* +-------------+ +-------------+
**********************************************************************
* Local monitor by name: (Ref is always same in all involved data structures)
**********************************************************************
* Process X Process Y (name foo)
* +-------------+ +-------------+
* Type: | MON_ORIGIN | | MON_TARGET |
* +-------------+ +-------------+
* Pid: | Pid(Y) | | Pid(X) |
* +-------------+ +-------------+
* Name: | Atom(foo) | | Atom(foo) |
* +-------------+ +-------------+
**********************************************************************
* Remote monitor by pid: (Ref is always same in all involved data structures)
**********************************************************************
* Node A | Node B
* ---------------------------------+----------------------------------
* Process X (@A) Distentry @A Distentry @B Process Y (@B)
* for node B for node A
* +-------------+ +-------------+ +-------------+ +-------------+
* Type: | MON_ORIGIN | | MON_TARGET | | MON_ORIGIN | | MON_TARGET |
* +-------------+ +-------------+ +-------------+ +-------------+
* Pid: | Pid(Y) | | Pid(X) | | Pid(Y) | | Pid(X) |
* +-------------+ +-------------+ +-------------+ +-------------+
* Name: | [] | | [] | | [] | | [] |
* +-------------+ +-------------+ +-------------+ +-------------+
**********************************************************************
* Remote monitor by name: (Ref is always same in all involved data structures)
**********************************************************************
* Node A | Node B
* ---------------------------------+----------------------------------
* Process X (@A) Distentry @A Distentry @B Process Y (@B)
* for node B for node A (name foo)
* +-------------+ +-------------+ +-------------+ +-------------+
* Type: | MON_ORIGIN | | MON_TARGET | | MON_ORIGIN | | MON_TARGET |
* +-------------+ +-------------+ +-------------+ +-------------+
* Pid: | Atom(node B)| | Pid(X) | | Pid(Y) | | Pid(X) |
* +-------------+ +-------------+ +-------------+ +-------------+
* Name: | Atom(foo) | | Atom(foo) | | Atom(foo) | | Atom(foo) |
* +-------------+ +-------------+ +-------------+ +-------------+
* The reason for the node atom in X->pid is that we don't know the actual
* pid of the monitored process on the other node when setting the monitor
* (which is done asyncronously).
**********************************************************************/
25 楼
qiezi
2007-07-31
mryufeng 写道
节点间的通讯协议见otp_src_R11B-5\erts\emulator\internal_doc\erl_ext_dist.txt
erl_interface 目前还不支持 link monitor的op, 只能send receive 数据。 理论上自己可以扩展ei 自己来解释这几条op
erl_interface 目前还不支持 link monitor的op, 只能send receive 数据。 理论上自己可以扩展ei 自己来解释这几条op
原来如此。看到这些协议了:
引用
4.2.1.1 LINK
{1, FromPid, ToPid}
4.2.1.3 EXIT
{3, FromPid, ToPid, Reason}
4.2.1.4 UNLINK
{4, FromPid, ToPid}
引用
4.4.1 MONITOR_P
{19, FromPid, ToProc, Ref}
FromPid = monitoring process
ToProc = monitored process pid or name (atom)
4.4.2 DEMONITOR_P
{20, FromPid, ToProc, Ref}
We include the FromPid just in case we want to trace this.
FromPid = monitoring process
ToProc = monitored process pid or name (atom)
4.4.3 MONITOR_P_EXIT
{21, FromProc, ToPid, Ref, Reason}
FromProc = monitored process pid or name (atom)
ToPid = monitoring process
Reason = exit reason for the monitored process
看样子都是基于Process的,难道monitor_node实际上是用link或monitor_p协议做出来的?不过我看erts/emulator/beam/dist.c里面有个monitor_node_3,但没有以public方式开放出来。
24 楼
mryufeng
2007-07-31
节点间的通讯协议见otp_src_R11B-5\erts\emulator\internal_doc\erl_ext_dist.txt
erl_interface 目前还不支持 link monitor的op, 只能send receive 数据。 理论上自己可以扩展ei 自己来解释这几条op
erl_interface 目前还不支持 link monitor的op, 只能send receive 数据。 理论上自己可以扩展ei 自己来解释这几条op
23 楼
qiezi
2007-07-31
iunknown 写道
另外,你们公司还是比较人性化啊,做得快,剩下的时间可以自己支配。最担心就是公司见你做得快,很好,再来一个!然后你变成了做得最快,但是最忙的人,呵呵。
我们公司是给自己做软件,作为WEB应用,稳定性比进度重要。通常逻辑也比较简单,只是要从系统架构上考虑任何一个点挂掉以后的备用策略。
----------------------------------------------------------------------------
这个帖子提到的erlang应用,我简单测试了一下还是可行的,简单总结一下用到的知识。
1、分布式结点发送消息注册服务:
{manager, 'a@xxx.xxx.xxx.xxx'} ! {reg_service, auth, self()}
2、监测节点退出:
monitor_node('a@xxx.xxx.xxx.xxx', true)
然后接收:
{nodedown, Node}
3、监测进程退出:
process_flag(trap_exit, true),
link(Pid)
4、远程节点心跳检测:
erl -heart
设置心跳间隔:
erl -heart -env HEART_BEAT_TIMEOUT 30 设置30秒心跳间隔,范围是10-65535秒之间。
有这些应该够用了。如果是C程序,如何发出monitor_node和process_flag/link呢?也可以从erlang节点上检测C节点,不过还是想知道反过来怎么检测。
22 楼
iunknown
2007-07-28
引用
长函数是普遍情况了,呵呵。比较合理的情况,公用库放在外面,项目特定的代码应该只有少于1/5的代码用来把一些库串联起来,而逻辑部分则应该占到1/2 或更多,其它都是完成架构不可少的胶合代码。但目前一些项目,几十个文件在一起,只有几个文件是逻辑的,但却不能离开其它文件单独拿来测试。逻辑处理基本上都是长函数,加上没有很好的利用分级日志,排错非常麻烦,服务器又不能经常重启去做调试。
出现长函数,或者模块划分不清楚,很多时候是由于开发人员没有清晰的分层意识,没有分清楚公用库和胶合代码。有时候有些库是从特定项目中重构出来的。在重构成库的过程中,没有考虑清楚这个库的主体功能,从而把一些胶合代码也被放到了库里面。导致这个库本身就依赖于太多的其他库。当需要使用这个库的时候,令人发狂的事情就开始了。
引用
我刚到这公司时,写代码就是有名的快,一周的任务都是一天之内完成,其实也不是很快,只不过大家都习惯了慢。搞C++的多半都喜欢调试而不喜欢单元测试,我正是使用这一简单的敏捷方式来提高开发效率,可测试的代码通常接口也比较好,重用性也会很好。
嗯,对于后台开发,很多复杂的情况,不用单元测试,可能还没那么容易模拟出来。单元测试一般来说,能够比较方便地模拟出自己想要的前提条件。
另外,你们公司还是比较人性化啊,做得快,剩下的时间可以自己支配。最担心就是公司见你做得快,很好,再来一个!然后你变成了做得最快,但是最忙的人,呵呵。
21 楼
qiezi
2007-07-28
iunknown 写道
我遇到的情况也类似。最常见的情况是长函数一大堆,或者因为模块划分不好,导致循环依赖。在这个坛子里,大多数人都认为 c++ 难学难精,但是在我遇到的情况中,好像是反过来,反而好像认为随便一个人都是 c++ 高手,有些重要的关于项目方面的决策也没怎么讨论,随便就交给了一个新手,结果就像 qiezi 说的:“很多C++项目,明显是生手的练习,各种漏洞一大堆”。
长函数是普遍情况了,呵呵。比较合理的情况,公用库放在外面,项目特定的代码应该只有少于1/5的代码用来把一些库串联起来,而逻辑部分则应该占到1/2或更多,其它都是完成架构不可少的胶合代码。但目前一些项目,几十个文件在一起,只有几个文件是逻辑的,但却不能离开其它文件单独拿来测试。逻辑处理基本上都是长函数,加上没有很好的利用分级日志,排错非常麻烦,服务器又不能经常重启去做调试。
iunknown 写道
呵呵,公司有那么宽松的时间给你? 口水ing 。。。。。。
我经常也有这样的想法,不过公司基本上不会答应。所以只好自己业余时间来试了。
我刚到这公司时,写代码就是有名的快,一周的任务都是一天之内完成,其实也不是很快,只不过大家都习惯了慢。搞C++的多半都喜欢调试而不喜欢单元测试,我正是使用这一简单的敏捷方式来提高开发效率,可测试的代码通常接口也比较好,重用性也会很好。初期大家都不放心,不过负责的几个项目都是最稳定的,也就没什么疑虑了。这样我每周可以省很多时间,几乎所有的时间都是在写代码或看书。对我来说时间还是充裕的,只不过喜欢的东西太杂太多,每样都搞点皮毛,所以显得也很忙。通常服务器系统写完测试上线还需要监控一段时间,这段时间基本上是不分配任务的,定时上去监控看一下日志就好,一般这些时间有些同事在聊天、下棋什么的(好像公司不反对),我拿这些时间看书或写代码。多点练习也是好的,我刚来时公司有很多各方面的专家,很短一段时间以后,我就发现他们的很多理论是错误的,很多都是在做项目的过程中看过一些文档后就深信不疑,而我喜欢写代码验证,所以一段时间以后我的意见就能成为更有参考价值的。
又跑题了。难怪说:3页之内必跑题,如果没跑肯定是前2页已经跑了。。
跑题也没什么,话题都是扩展的,如果能把一个帖子的各个回帖打标签就好了,连在一起看时也可以知道是怎么跑到这个话题上的,分开看也价值。
20 楼
iunknown
2007-07-28
qiezi 写道
倒是公司现有的很多C++项目,明显是生手的练习,各种漏洞一大堆,几乎所有的项目都被补过一遍了,可维护性是有,却是很需要维护啊,而且维护的成本也不低。
我遇到的情况也类似。最常见的情况是长函数一大堆,或者因为模块划分不好,导致循环依赖。在这个坛子里,大多数人都认为 c++ 难学难精,但是在我遇到的情况中,好像是反过来,反而好像认为随便一个人都是 c++ 高手,有些重要的关于项目方面的决策也没怎么讨论,随便就交给了一个新手,结果就像 qiezi 说的:“很多C++项目,明显是生手的练习,各种漏洞一大堆”。
qiezi 写道
几乎每个项目我都实现过多种可选方案,然后进行比较,再找一下各种方案的差异,当然最后上线的肯定是C++版本的,每种方案都做完了,都是可以上线的版本,上哪个版本正是考虑到以后的维护性问题。
呵呵,公司有那么宽松的时间给你? 口水ing 。。。。。。
我经常也有这样的想法,不过公司基本上不会答应。所以只好自己业余时间来试了。
19 楼
qiezi
2007-07-27
dustinth 写道
那估计你们公司没什么希望. 不考虑以后维护性方面的问题. 我自己也挺讨厌想LZ这种所谓的"牛人", 自己随自己喜欢, 那公司的东西做实验, 做烂了就拍拍屁股走人.
python应用这么广,公司大部分人都会,会C++的学python几天就可以上手,而且公司目前大力推广C++配合脚本语言开发业务逻辑,我带个头而已。erlang我还没应用到项目中呢,用的人毕竟是少,很多时候有些项目都是临时性的,解决一时的问题,过渡性方案,要求快速开发,用完就没什么用了,所以我经常会在各个项目里临时救一下火,或者是要快速做一下原型,你不得找个开发效率和运行效率都过得去的东西?另外模块化的开发很容易维护,都是分布式系统,协议兼容就可以了。倒是公司现有的很多C++项目,明显是生手的练习,各种漏洞一大堆,几乎所有的项目都被补过一遍了,可维护性是有,却是很需要维护啊,而且维护的成本也不低。
我在公司基本上所有时间都在写代码,这是唯一爱好,一个项目完了如果有其它可选方案我肯定会试试,或者是其它语言来实现,你经常会看到我说用什么语言做项目,那是因为我完成了现有项目,多出来的时间我做些尝试而已,其他同事完成项目后都在聊天或看网站,我不过是做点不同的事而已。几乎每个项目我都实现过多种可选方案,然后进行比较,再找一下各种方案的差异,当然最后上线的肯定是C++版本的,每种方案都做完了,都是可以上线的版本,上哪个版本正是考虑到以后的维护性问题。你说做实验也可以,至少我没搞砸过一个项目,否则我早被开掉了。关于公司,在不到2年时间里,日浏览量目前已经接近搜狐,你要说没什么希望我也不需要反驳。。。每种公司都有自己的文化氛围,越是成功的公司越会鼓励员工尝试新技术,而不是以各种理由去阻碍。拍拍屁股走人更不是我的风格,我在过去工作过的地方时间都很长,不要拿自己的习惯去猜度别人。
又要成吵架帖了。最后说几句:
1、怀疑别人的人品的话不要说,除非你有证据证明我人品有问题。
2、明确的对别人说你讨厌他这种类型,很明显是一种挑衅行为,版规所不容。
18 楼
dustinth
2007-07-27
qiezi 写道
iunknown 写道
qiezi 写道
找了源代码看了,应该不是线程安全的,一个消息发送就有多个写操作,并发的写FD肯定有问题的。
HIDDEN NODE没有提供更多东西,只是隐藏而已,其它没区别。
这个架构准备在项目中试用一下了,以后服务调用、服务器间通讯都是走erlang节点了。
HIDDEN NODE没有提供更多东西,只是隐藏而已,其它没区别。
这个架构准备在项目中试用一下了,以后服务调用、服务器间通讯都是走erlang节点了。
qiezi 是怎么说服公司使用 erlang 的?我对这一点比较好奇
还没说服啊,公司并不看我写代码,项目搞稳定就行了,我已经把一部分用python写了,其它部分则使用了一些第三方库比如log4cxx,同事项目有问题就会看我怎么做,看了也会学着用的。目前有些部分本来就是独立的进程,用配置文件去定义功能,然后组合到新的服务器中,用什么语言实现都没多大差别了,稳定、高效就是唯一追求。
那估计你们公司没什么希望. 不考虑以后维护性方面的问题. 我自己也挺讨厌想LZ这种所谓的"牛人", 自己随自己喜欢, 那公司的东西做实验, 做烂了就拍拍屁股走人.
17 楼
mryufeng
2007-07-25
There are two different interfaces, the old 'erl_interface' and 'ei'.
The old interface is to depend on the new one, not the other way arount.
Erl_interface should bze "thread safe", i.e. you should be able to
handle connections, convert data etc from different threads.
Ei should be "reentrant" or "async safe", i.e. no locks should be set
so that if an ei function is called inside an signal handler there
could be a deadlock.
VxWorks call the operating processes "tasks". These are to be handled the
same way as Unix threads, i.e. there can only be one C node for all tasks
using the old interface.
The old interface is to depend on the new one, not the other way arount.
Erl_interface should bze "thread safe", i.e. you should be able to
handle connections, convert data etc from different threads.
Ei should be "reentrant" or "async safe", i.e. no locks should be set
so that if an ei function is called inside an signal handler there
could be a deadlock.
VxWorks call the operating processes "tasks". These are to be handled the
same way as Unix threads, i.e. there can only be one C node for all tasks
using the old interface.
16 楼
mryufeng
2007-07-21
cnode的实现非常薄 没有任何防护措施 这不是erl_interface的错。 ei的价值在于给你一把匕首 你能够很方便地切肉吃 当然有可能伤到手。
15 楼
Trustno1
2007-07-19
以前potain提醒过,cnode非常不稳定.运行几天就会有没有原因的内核crash.
14 楼
qiezi
2007-07-18
firebody 写道
赫赫,跟我猜测的不大一样,没做过实际测试,原来估计 两个线程的切换和 四个线程的切换,系统在切换上所花的时间应该差别不大,照你实际情况来看,我的估计还是错误的。
看具体情况吧,网游这种计算集中的,数据都从外部主动输入,当然是线程数少比较好,目前很多网游都是单线程跑逻辑。一些中间层服务封装数据库、远程服务调用和事务的,通常IO延时会比较明显,这时候多个线程效果比较好。这2种情况下erlang都是适用的。
13 楼
firebody
2007-07-18
qiezi 写道
firebody 写道
有个疑问:
Erlang高并发性能的主要思想来自于 独立于操作系统的本身自带的进程调度系统,Erlang的进程切换非常高效,
现在你的设计 是 C node 大量系统线程切换+Erlang的高并发服务器。 前者会不会是个瓶颈所在? 使得系统退化回了 传统的服务器设计? 传统设计上的进程/线程 切换开销太大了。
Erlang高并发性能的主要思想来自于 独立于操作系统的本身自带的进程调度系统,Erlang的进程切换非常高效,
现在你的设计 是 C node 大量系统线程切换+Erlang的高并发服务器。 前者会不会是个瓶颈所在? 使得系统退化回了 传统的服务器设计? 传统设计上的进程/线程 切换开销太大了。
可以设置成erlang使用一个线程,C node开3线程,一共4个,在4CPU上运行,目前使用的服务器都是4CPU的,部分高档货8CPU。通常运行时线程数会更多,因为各种IO都会影响,我测试线程数达到十几个才会明显感觉到线程切换的影响,这个数字也和测试的具体业务相关,通常是根据测试情况来配置。
赫赫,跟我猜测的不大一样,没做过实际测试,原来估计 两个线程的切换和 四个线程的切换,系统在切换上所花的时间应该差别不大,照你实际情况来看,我的估计还是错误的。
12 楼
mryufeng
2007-07-17
个人感觉是cnode是做些比较难用erlang实现的东西如和操作系统或者硬件交互之类的事情,调用的频率不是很高。 但是实现和调试起来又比较麻烦的场合。
11 楼
qiezi
2007-07-17
firebody 写道
有个疑问:
Erlang高并发性能的主要思想来自于 独立于操作系统的本身自带的进程调度系统,Erlang的进程切换非常高效,
现在你的设计 是 C node 大量系统线程切换+Erlang的高并发服务器。 前者会不会是个瓶颈所在? 使得系统退化回了 传统的服务器设计? 传统设计上的进程/线程 切换开销太大了。
Erlang高并发性能的主要思想来自于 独立于操作系统的本身自带的进程调度系统,Erlang的进程切换非常高效,
现在你的设计 是 C node 大量系统线程切换+Erlang的高并发服务器。 前者会不会是个瓶颈所在? 使得系统退化回了 传统的服务器设计? 传统设计上的进程/线程 切换开销太大了。
可以设置成erlang使用一个线程,C node开3线程,一共4个,在4CPU上运行,目前使用的服务器都是4CPU的,部分高档货8CPU。通常运行时线程数会更多,因为各种IO都会影响,我测试线程数达到十几个才会明显感觉到线程切换的影响,这个数字也和测试的具体业务相关,通常是根据测试情况来配置。
10 楼
firebody
2007-07-17
有个疑问:
Erlang高并发性能的主要思想来自于 独立于操作系统的本身自带的进程调度系统,Erlang的进程切换非常高效,
现在你的设计 是 C node 大量系统线程切换+Erlang的高并发服务器。 前者会不会是个瓶颈所在? 使得系统退化回了 传统的服务器设计? 传统设计上的进程/线程 切换开销太大了。
Erlang高并发性能的主要思想来自于 独立于操作系统的本身自带的进程调度系统,Erlang的进程切换非常高效,
现在你的设计 是 C node 大量系统线程切换+Erlang的高并发服务器。 前者会不会是个瓶颈所在? 使得系统退化回了 传统的服务器设计? 传统设计上的进程/线程 切换开销太大了。
9 楼
qiezi
2007-07-17
javavsnet 写道
qiezi 写道
还没说服啊,公司并不看我写代码,项目搞稳定就行了,我已经把一部分用python写了,其它部分则使用了一些第三方库比如log4cxx,同事项目有问题就会看我怎么做,看了也会学着用的。目前有些部分本来就是独立的进程,用配置文件去定义功能,然后组合到新的服务器中,用什么语言实现都没多大差别了,稳定、高效就是唯一追求。
qiezi你在实现哪些功能的时候用了python?说说看,我想借鉴你的经验。
运行效率要求不是特别高的地方都可以用,比如日志服务器、文件服务器、大量的压力测试程序、文本处理等。
相关推荐
JESD79-2F DDR2 JESD79-3F DDR3 JESD79-4D DDR4 JESD79-5C DDR5 JESD209-2F LPDDR2 JESD209-3C LPDDR3 JESD209-4E LPDDR4 JESD209-4-1A LPDDR4X JESD209-5C LPDDR5(X)
COMSOL二维光子晶体角态研究:单胞与超胞能带计算及边界态与角态特性分析,COMSOL二维光子晶体角态研究:单胞与超胞能带计算及边界态与角态特性分析,comsol二维光子晶体角态。 单胞能带,超胞能带,边界态以及角态计算。 ,comsol;二维光子晶体;角态;单胞能带;超胞能带;边界态计算,基于Comsol的二维光子晶体角态及能带边界计算研究
六自由度机械臂抓取动作仿真与代码解析:抓取动画、关节参数变化及轨迹图解详解,六自由度机械臂抓取动作仿真指南:掌握两套代码实现动画与轨迹图模拟学习攻略,六自由度机械臂抓取动作仿真-8 两套关于抓取动作的代码,包括抓取动画、关节角、角速度、角加速度的变化仿真、以及抓取轨迹图 简单易懂好上手~ ,六自由度机械臂;抓取动作仿真;抓取动画;关节角变化;角速度角加速度;抓取轨迹图;两套代码;简单易懂好上手,六自由度机械臂抓取动作仿真演示:代码与轨迹图解
ITC网络广播工具软件
Multisim四位密码锁电路仿真设计:设定、开锁与声光报警功能演示资料包,Multisim四位密码锁电路仿真设计:设定、输入、开锁与报警功能详解,附源文件、原理说明书与演示视频,multisim四位密码锁电路仿真设计 功能: 1.通过拨码开关1进行初始密码设定。 2.通过拨码开关2输入密码,实现开锁判断。 3.如果密码正确,LED绿灯亮,表示开锁。 4.如果密码不正确,LED红灯亮,蜂鸣器鸣叫,声光报警。 资料包含:仿真源文件+原理说明书+演示视频 ,四位密码锁电路、Multisim仿真设计、初始密码设定;拨码开关输入;开锁判断;LED灯显示;声光报警;仿真源文件;原理说明书;演示视频,Multisim四位密码锁电路仿真设计:初始密码设置与智能解锁功能的声光报警展示
俗话说,摸鱼摸的好,上班没烦恼,毕竟谁能拒绝带薪拉屎呢(手动狗头) 这是一个云开发职场打工人专属上班摸鱼划水微信小程序源码,没有后台 直接导入微信开发者工具即可运行,UI简约大气漂亮,只需登录微信公众平台配置完合法域名即可轻松上线。 用户进入摸鱼小程序,可以自由设置薪资,上班时间、下班时间、发薪日、 月工作天数以提醒自己摸鱼,全民打酱油,让自己成为摸鱼冠军,《商鞅摸鱼哲学》 摸鱼不是自我放纵,而是个人实力的积蓄,我们的小目标是晚睡晚起 小程序中的今日待办会提醒用户带薪拉屎和闲逛,下方展示的是距离休息日的天数,距离下一次发工资的天数和节日的天数。
【毕业设计】基于Java的开发的一个集合校园二手交易、拼车、失物招领等功能的app_pgj
个人记录:PICkit3离线烧录流程 使用软件:MPLAB X IDE v5.30 记录时间:20250215
基于Matlab代码的电力系统状态估计与实验仿真研究:扩展卡尔曼滤波和无迹卡尔曼滤波在电力系统动态状态估计中的应用及效果分析,Matlab仿真实验研究:基于扩展卡尔曼滤波器与无迹卡尔曼滤波器对电力系统状态估计的影响及验证,状态估计 电力系统状态估计 Matlab代码 实验仿真研究 电力系统由于测量值和传输误差,还有测量噪声的影响,会对状态估计产生影响。 因此,需要对嘈杂的测量进行滤波,以获得准确的电力系统运行动态。 本文使用扩展卡尔曼滤波器(EKF)和无迹卡尔曼滤波器(UKF)来估计电力系统的动态状态。 扩展卡尔曼滤波EKF、无迹卡尔曼滤波UKF 利用扩展的无迹卡尔曼滤波器估计了动力系统的动态状态。 对WECC 3机9总线系统和新英格兰10机39总线系统进行了案例研究。 结果表明EKF和UKF都能准确地估计电力系统的动态状态。 ,核心关键词:状态估计; 电力系统状态估计; Matlab代码; 实验仿真; 测量值误差; 测量噪声; 扩展卡尔曼滤波器(EKF); 无迹卡尔曼滤波器(UKF); 动力系统; 动态状态估计; WECC 3机9总线系统; 新英格兰10机39总线系统。,Matlab
springboot在线考试--
台达DVP EH3与MS300 PLC&变频器通讯程序的全面解决方案,台达DVP EH3与MS300通讯程序:稳定可靠的频率控制与启停管理系统,台达DVP EH3与台达MS300通讯程序(TDEH-9) 可直接用于实际的程序,程序带注释,并附送触摸屏程序,有接线方式和设置,通讯地址说明等。 程序采用轮询,可靠稳定 器件:台达DVP EH3系列PLC,台达MS300系列变频器,昆仑通态7022Ni 功能:实现频率设定,启停控制,实际频率读取,加减速时间设定。 资料:带注释程序,触摸屏程序,接线和设置说明,后续有技术咨询。 ,核心关键词:台达DVP EH3; 台达MS300; 通讯程序(TDEH-9); 轮询; 稳定; 频率设定; 启停控制; 实际频率读取; 加减速时间设定; 触摸屏程序; 接线方式; 设置说明; 技术咨询。,台达PLC与变频器通讯程序(带注释、触摸屏控制)
项目资源包含:可运行源码+sql文件 适用人群:学习不同技术领域的小白或进阶学习者;可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。项目具有较高的学习借鉴价值,也可拿来修改、二次开发。 个人账户管理:支持用户注册、登录与个人信息编辑;提供密码找回及账号安全保护措施。 声纹采集:利用麦克风设备录制用户的声纹样本;支持多种录音格式和质量调整,确保采集到清晰、准确的声纹数据。 声纹模板库管理:建立和维护一个安全的声纹模板库;支持声纹模板的添加、删除、更新和查询操作。 声纹比对与识别:运用深度学习算法对输入的声纹数据进行特征提取和匹配;实现快速、准确的声纹身份验证。 多场景应用支持:适用于多种场景,如门禁系统、移动支付、远程登录等;可根据实际需求定制开发相应的应用场景。 实时监控与报警:实时监控系统运行状态,包括声纹识别成功率、处理速度等指标;当出现异常情况时,及时发出报警信息。 数据分析与报告生成:收集并分析声纹识别过程中的数据,如识别准确率、处理时间等;根据用户需求输出包含详细图表说明的专业级文档供下载打印保存。 社区互动交流:设立论坛版块鼓励用户分享心得体会讨论热点话题;定期邀请行业专家举办线上讲座传授实用技巧知识。 音乐筛选与推荐:集成音乐平台API,根据用户的浏览习惯和情绪状态推荐背景音乐,增强用户体验。 数据可视化:提供交互式的数据可视化面板,使非技术用户也能轻松理解复杂的数据集,从而做出更明智的决策。
三相与多相开绕组永磁同步电机仿真模型的先进控制策略探讨与实现,三相与多相开绕组永磁同步电机的Simulink仿真模型与先进控制策略研究,开绕组电机,开绕组永磁同步电机仿真模型、simulink仿真 共直流母线、独立直流母线,两相容错,三相容错控制,零序电流抑制,控制策略很多 三相开绕组永磁同步电机,六相开绕组永磁同步电机 五相开绕组永磁同步电机,五相开绕组电机 ,开绕组电机; 永磁同步电机仿真模型; simulink仿真; 共直流母线; 独立直流母线; 两相容错; 三相容错控制; 零序电流抑制; 控制策略; 六相开绕组永磁同步电机; 五相开绕组永磁同步电机,开绕组电机仿真研究:共直流母线与独立直流母线的容错控制策略
【毕业设计】基于Java的开发的网上汽车租赁管理系统_pgj
csv 模块是 Python 的标准库,无需额外安装。 运行结果如下图: ['姓名', '年龄', '城市'] ['张三', '25', '北京'] ['李四', '30', '上海'] ['王五', '22', '广州']
【毕业设计】基于Java+Springboot+Vue的宠物领养系统_pgj
让前端开发者学习“机器学习”!
【毕业设计】基于Java的实现的以宠物为主体的论坛式的APP
大模型应用工具实战2-有好玩的数字人
【毕业设计】基于ssm的选课管理系统