- 浏览: 500073 次
- 性别:
- 来自: 上海
-
文章分类
最新评论
-
hypercube:
markin'
配置D语言编程环境 -
qiezi:
qiezi 写道yangyang_08 写道1 ...
我的编程语言学习经历 -
qiezi:
yangyang_08 写道1、现在如果做并发服务器,楼主选用 ...
我的编程语言学习经历 -
yangyang_08:
1、现在如果做并发服务器,楼主选用什么样的语言架构?2、lua ...
我的编程语言学习经历 -
dearplain:
我也是语言爱好者,不过我一直坚持使用c。
我的编程语言学习经历
琢磨了好久,一直没时间来做它。在讨论这个问题的时候就已经有这想法了,后来发现tango里已经有Fiber的实现,昨天终于抽了点时间做了个简单的小玩意,离真实应用还差得很远。
测试代码:
实现:
依赖tango。
目前只实现了基本的消息发送接收,为了简单目前使用内置数组来保存数据。整个驱动过程是对所有进程顺序进行调度,没有过优化是否有需要调度,只是快速做了个原型。timeout功能也没有实现,这个有时间可以重写调度部分来完成,因为这个部分就是随意写了一个,测试是否有可能实现类似erlang的高度过程。所以这个驱动过程实际上是个死循环,测试几秒就强行结束程序吧,CPU被烧本人概不负责。
递归是比较麻烦的,不知道D有没有优化尾递归,我想应该还是有的吧,不然上面那个程序应该早就溢出了。receive的各个委托参数里是没办法优化成尾递归的,解决办法当然有,就是麻烦点,谁叫咱不是FP语言呢。。(这年头,不是FP你都感觉抬不起头。。。)
erlang 这么强, 比专门写的代码都强, 原因何在呢 ?
哦, 对了 python 的代码是一来就关闭 gc的, 你做了这个没有.
原来如此,这个测试D/C++成绩也太差了,线程开销还是太大了些,应该很容易用轻量级线程来提高吧。目前首先要做的是做个调度器,先让它跑起来再说。
fiber不一定会比thread性能高的,特别是大量计算的只会降低效率。只是更容易生成大量的“线程”,提高并行能力。如果实现erlang这种架构,就可以让程序写起来更方便,用同步的写法就完成了异步的调用,对于库的编写要求会比较高。
上面这个测试程序只是简单测试一下可行性,看有没有人有兴趣一起研究一下,这种架构最主要的难点在于调度,不过这是个不断优化的过程,关键是看有没有简化编程。D的垃圾收集对于委托的影响还没测试到呢,它和fiber的配合程度怎样也不清楚,毕竟fiber的堆栈是要不断切换的,而D的GC在扫描堆栈时只是扫描线程栈。
是更容易做成并行,但这也依赖于实现。
测试代码:
import light_process; import tango.io.Stdout; void test() { Stdout("test").newline; receive( (Process pid, float f) { Stdout("test: receive float: ", f).newline; pid.send(f); }, (Process pid, int i) { Stdout("test: receive int: ", i).newline; pid.send(i * 2); }, (NotMatched) { Stdout("test: not matched").newline; } ).timeout(3000, { Stdout("test: timeout").newline; }).end; test(); } void test1(Process pid){ Stdout("test1").newline; //sleep(1); pid.send(self(), 7.7f); pid.send(self(), cast(int)3); test1_loop(); } void test1_loop() { receive( (float f) { Stdout("test1: received result: ", f).newline; }, (int value) { Stdout("test1: received result: ", value).newline; } ).timeout(3000, { Stdout("test1: timeout").newline; }).end; test1_loop(); } void sleep(size_t usecs) { receive( ).timeout(usecs, { }).end; } void de_start() { auto pid = spawn(&test); spawn(&test1, pid); //sleep(3); } void main(){ de_start(); Process.run(); }
实现:
module light_process; import tango.core.Thread; import tango.core.Traits; class NotMatched{ } class Message { TypeInfo typeInfo__; public this(TypeInfo typeInfo__) { this.typeInfo__ = typeInfo__; } } class MessageT(Types...) : public Message{ Types values; public this(Types values_){ super(typeid(typeof(Types))); foreach(i, e; values_) { values[i] = values_[i]; } } } class Delegate { abstract void call(Message msg); abstract bool matchType(TypeInfo typeInfo__); } class DelegateT(Types...) : public Delegate{ void delegate(Types) dg; void function(Types) func; this(void delegate(Types) dg){ this.dg = dg; } this(void function(Types) func){ this.func = func; } override void call(Message msg) { auto message = cast(MessageT!(Types))msg; if (dg) dg(message.values); else func(message.values); } override bool matchType(TypeInfo typeInfo__) { if (typeid(Types) is typeid(NotMatched) || typeInfo__ is typeid(Types)) return true; return false; } } class Process : public Fiber{ // static members public static Process getThis() { return cast(Process)Fiber.getThis(); } private static Process[] processes; // instance members private Message[] messages; private Delegate[] handlers; public this() { super(&exec); } public void clearMessageHandlers() { handlers.length = 0; } public void addMessageHandler(Delegate dg){ handlers ~= dg; } public Process timeout(int timeout, void delegate() dg) { return this; } public void end() { Fiber.yield(); domsg(); } public Process send(Args ...)(Args args) { messages ~= new MessageT!(Args)(args); return this; } public void domsg() { while (!messages.length) { Fiber.yield(); } Message msg = messages[0]; foreach(dg; handlers) { if (dg.matchType(msg.typeInfo__)) { dg.call(msg); messages = messages[1..$]; break; } } } public static void run() { while(true) { foreach(process; Process.processes) { if (process.state != Fiber.State.TERM) { process.call(); } } } } protected abstract void exec(); } class ProcessT(Ret, Args...) : public Process { Ret delegate(Args) dg; Ret function(Args) func; Args args; public this(Ret delegate(Args) dg, Args args) { this.dg = dg; foreach(i, e; args) { this.args[i] = e; } } public this(Ret function(Args) func, Args args) { this.func = func; foreach(i, e; args) { this.args[i] = e; } } public void exec() { if (dg) dg(args); else func(args); } } Process spawn(Ret, Args...)(Ret delegate(Args) dg, Args args) { Process p = new ProcessT!(Ret, Args)(dg, args); Process.processes ~= p; return p; } Process spawn(Ret, Args...)(Ret function(Args) func, Args args) { Process p = new ProcessT!(Ret, Args)(func, args); Process.processes ~= p; return p; } Process receive(Dgs ...)(Dgs dgs) { Process self = Process.getThis(); self.clearMessageHandlers(); foreach(i, dg; dgs) { Delegate handler = new DelegateT!(ParameterTupleOf!(typeof(dgs[i]))) (dgs[i]); self.addMessageHandler(handler); } return self; } Process self() { return Process.getThis(); }
依赖tango。
目前只实现了基本的消息发送接收,为了简单目前使用内置数组来保存数据。整个驱动过程是对所有进程顺序进行调度,没有过优化是否有需要调度,只是快速做了个原型。timeout功能也没有实现,这个有时间可以重写调度部分来完成,因为这个部分就是随意写了一个,测试是否有可能实现类似erlang的高度过程。所以这个驱动过程实际上是个死循环,测试几秒就强行结束程序吧,CPU被烧本人概不负责。
递归是比较麻烦的,不知道D有没有优化尾递归,我想应该还是有的吧,不然上面那个程序应该早就溢出了。receive的各个委托参数里是没办法优化成尾递归的,解决办法当然有,就是麻烦点,谁叫咱不是FP语言呢。。(这年头,不是FP你都感觉抬不起头。。。)
评论
18 楼
qiezi
2007-09-18
可气的是python也这么快。。。
17 楼
qiezi
2007-09-18
优化到9秒了,感觉没办法进一步提高了,从12秒到9秒的一点提高就是Delegate对象改成scope了,直接在栈上分配。
erlang的这个应用实际上所有进程都没有退出,直到最后执行exit前没有进程退出,所以可能还没到清扫那一步,但它的内存占用也比较低,还是可以进一步分析一下。
erlang的这个应用实际上所有进程都没有退出,直到最后执行exit前没有进程退出,所以可能还没到清扫那一步,但它的内存占用也比较低,还是可以进一步分析一下。
16 楼
tomqyp
2007-09-18
为什么动态语言在这方面都好强,那个mozart-oz看它的语言特性介绍好像也很酷
15 楼
Trustno1
2007-09-18
erlang的私有堆清扫非常方便,process退出,整个私有堆就撤掉.完全不用管其他的process里面的东西.而D/python这样的共享堆需要清扫的根集非常之大.python关掉gc disable能够跑的快,是因为python最早的gc是基于reference counting实现的,关闭gc相当于启用reference counting,对于cheap-concurrency这种应用,reference counting比mark-sweep GC省力很多,只要你不出reference cycles.而D的gc disable只是在性能攸关但是内存充足的情况下允许程序员关闭GC完全不清扫垃圾,等到性能瓶颈运算过去之后,再由程序员手工打开gc清扫垃圾,是一个纯粹空间换时间的策略.
14 楼
qiezi
2007-09-18
看样子没办法让它提速500倍,优化调度过程,把LinkSeq换成D的数组以后,提升到12秒,D的线程版本只用8秒,erlang才1秒多,所以还相差很多。erlang是在windows上测试的,如果是linux下,HiPE应该还可以更快。
13 楼
qiezi
2007-09-18
这个测试目前erlang是排第二的,他的轻量级线程切换开销比fiber/ucontext更小,实际上python版本也排在c++/D前面.
erlang版本在我的机器上运行是1秒多,我的D版本运行是304秒,如果真能加速500倍的话倒是可以超过它.我测试了关闭GC,结果内存用到640M,用到了交换文件,成绩反而下降了.
erlang版本在我的机器上运行是1秒多,我的D版本运行是304秒,如果真能加速500倍的话倒是可以超过它.我测试了关闭GC,结果内存用到640M,用到了交换文件,成绩反而下降了.
12 楼
redsea
2007-09-18
他这个是比较公平的,各种语言都可以针对测试做特别的优化,那个gcc的版本就有用ucontext的,调度时甚至是按消息发送的顺序进行调度,但就是跑不过erlang。。所以我这个版本估计也不会好。 现在没做任何优化,每次都要调度500个“进程”,实际上每次只有一个进程有消息,所以最理想情况下能提速500倍,我计算过似乎还是比不上erlang版本。
erlang 这么强, 比专门写的代码都强, 原因何在呢 ?
哦, 对了 python 的代码是一来就关闭 gc的, 你做了这个没有.
11 楼
qiezi
2007-09-18
他这个是比较公平的,各种语言都可以针对测试做特别的优化,那个gcc的版本就有用ucontext的,调度时甚至是按消息发送的顺序进行调度,但就是跑不过erlang。。所以我这个版本估计也不会好。
现在没做任何优化,每次都要调度500个“进程”,实际上每次只有一个进程有消息,所以最理想情况下能提速500倍,我计算过似乎还是比不上erlang版本。
现在没做任何优化,每次都要调度500个“进程”,实际上每次只有一个进程有消息,所以最理想情况下能提速500倍,我计算过似乎还是比不上erlang版本。
10 楼
redsea
2007-09-18
to: DavidL
shootout 的代码都是用户自己提供的, 算不上不公平, 如果qiezi 优化好了他的代码, 一样可以提供上去, 只要符合规定, 结果正确, 可以取代原来的代码作为 D 的性能基准的.
tango 的fibre据说是assertfalse.com mikolalysenko的coroutine。language shootout的coroutine测试我不太懂其他语言的实现,然而感觉是对D不公平的,D用的是系统的线程。其他的可能根本就没有启动系统线程
shootout 的代码都是用户自己提供的, 算不上不公平, 如果qiezi 优化好了他的代码, 一样可以提供上去, 只要符合规定, 结果正确, 可以取代原来的代码作为 D 的性能基准的.
9 楼
qiezi
2007-09-18
做了个可工作的版本,完成cheap_concurrency的功能,结果是正确的,不过效率那是相当地低,主要是调度部分并没有优化。优化的策略就是每次只调度处于receive状态并且有message的进程,有空再进行,可能要这周末了。先发出来,有兴趣的不妨改改看。纯属好玩,不一定有什么价值。
cheap_concurrency测试代码是从erlang版本改过来的,不过由于递归会导致堆栈溢出,所以这里改成了循环。
1.cheap_concurrency.d
2.light_process.d
cheap_concurrency测试代码是从erlang版本改过来的,不过由于递归会导致堆栈溢出,所以这里改成了循环。
1.cheap_concurrency.d
import light_process; import tango.io.Stdout; import tango.text.convert.Integer; void de_main(int N) { Process Last = start(500, self()); Stdout(sendtimes(N, Last, 0)).newline; } Process start(int X, Process LastPID) { if (X == 0) return LastPID; return start(X-1, spawn(&loop, LastPID)); } void loop(Process LastPID) { while(true) { receive( (int N) { LastPID.send(N+1); } ).end; } } int sendtimes(int N, Process Last, int X) { for(int i=0; i<N; i++) { Last.send(0); int y; receive( (int Y) { y = Y; } ).end; X += y; } return X; } void main(char[][] args){ if (args.length != 2){ Stdout("USAGE: " ~ args[0] ~ " N").newline; return; } int n = toInt(args[1]); spawn(&de_main, n); Process.run(); }
2.light_process.d
module light_process; import tango.io.Stdout; import tango.core.Thread; import tango.core.Traits; import tango.util.collection.LinkSeq; class NotMatched{ } class Message { TypeInfo typeInfo__; public this(TypeInfo typeInfo__) { this.typeInfo__ = typeInfo__; } } class MessageT(Types...) : public Message{ Types values; public this(Types values_){ super(typeid(typeof(Types))); foreach(i, e; values_) { values[i] = values_[i]; } } } class Delegate { abstract void call(Message msg); abstract bool matchType(TypeInfo typeInfo__); } class DelegateT(Types...) : public Delegate{ void delegate(Types) dg; void function(Types) func; this(void delegate(Types) dg){ this.dg = dg; } this(void function(Types) func){ this.func = func; } override void call(Message msg) { auto message = cast(MessageT!(Types))msg; if (dg) dg(message.values); else func(message.values); } override bool matchType(TypeInfo typeInfo__) { if (typeid(Types) is typeid(NotMatched) || typeInfo__ is typeid(Types)) return true; return false; } } class Process : public Fiber{ // static members public static Process getThis() { return cast(Process)Fiber.getThis(); } // receiving processes private static bool[Process] receivingProcesses; // instance members private LinkSeq!(Message) messages; private LinkSeq!(Delegate) handlers; public this() { super(&exec); messages = new LinkSeq!(Message); handlers = new LinkSeq!(Delegate); } public void startReceiving() { receivingProcesses[this] = true; } public void stopReceiving() { receivingProcesses.remove(this); } public void clearMessageHandlers() { handlers.clear(); } public void addMessageHandler(Delegate dg){ handlers.append(dg); } public Process timeout(int timeout, void delegate() dg) { return this; } public void end() { Fiber.yield(); domsg(); } public Process send(Args ...)(Args args) { messages.append(new MessageT!(Args)(args)); return this; } public void domsg() { while(messages.size() == 0) { Fiber.yield(); } Message msg = messages.head(); foreach(dg; handlers) { if (dg.matchType(msg.typeInfo__)) { dg.call(msg); messages.removeHead(); break; } } } public static void run() { while(true) { foreach(process, dummy; Process.receivingProcesses) { if (process.state != Fiber.State.TERM) { process.call(); } } } } protected abstract void exec(); } class ProcessT(Ret, Args...) : public Process { Ret delegate(Args) dg; Ret function(Args) func; Args args; public this(Ret delegate(Args) dg, Args args) { this.dg = dg; foreach(i, e; args) { this.args[i] = e; } } public this(Ret function(Args) func, Args args) { this.func = func; foreach(i, e; args) { this.args[i] = e; } } public void exec() { if (dg) dg(args); else func(args); } } Process spawn(Ret, Args...)(Ret delegate(Args) dg, Args args) { Process p = new ProcessT!(Ret, Args)(dg, args); p.call(); return p; } Process spawn(Ret, Args...)(Ret function(Args) func, Args args) { Process p = new ProcessT!(Ret, Args)(func, args); p.call(); return p; } Process receive(Dgs ...)(Dgs dgs) { Process pid = self(); pid.clearMessageHandlers(); foreach(i, dg; dgs) { Delegate handler = new DelegateT!(ParameterTupleOf!(typeof(dgs[i])))(dgs[i]); pid.addMessageHandler(handler); } pid.startReceiving(); return pid; } Process self() { return Process.getThis(); }
8 楼
qiezi
2007-09-17
看样子要跑过erlang很难啊,那里有一个gcc的测试,使用ucontext的,竟然比python还差,更不用说erlang了。。
7 楼
DavidL
2007-09-16
tango的fibre据说是assertfalse.com mikolalysenko的coroutine。language shootout的coroutine测试我不太懂其他语言的实现,然而感觉是对D不公平的,D用的是系统的线程。其他的可能根本就没有启动系统线程
6 楼
qiezi
2007-09-15
redsea 写道
language shootout 里面那个测试基本没有实质计算, 每个 cheap thread 将自己收到的 token 传递给下一个 cheap thread 而已. 测试当中可以关闭 gc.
这个测试对 er-lang 来说, 简直是量身定做
这个测试对 er-lang 来说, 简直是量身定做
![](/images/smiles/icon_smile.gif)
原来如此,这个测试D/C++成绩也太差了,线程开销还是太大了些,应该很容易用轻量级线程来提高吧。目前首先要做的是做个调度器,先让它跑起来再说。
5 楼
redsea
2007-09-15
language shootout 里面那个测试基本没有实质计算, 每个 cheap thread 将自己收到的 token 传递给下一个 cheap thread 而已. 测试当中可以关闭 gc.
这个测试对 er-lang 来说, 简直是量身定做
这个测试对 er-lang 来说, 简直是量身定做
![](/images/smiles/icon_smile.gif)
4 楼
qiezi
2007-09-15
redsea 写道
language shootout 那里有个 cheap concurrent 测试, 就是测试类似能力的.
er-lang 的表现不错.
D 的程序记得没有用 fiber, 被人用 thread 去实现的, qiezi 不妨去提交一个 fiber 的版本, 提高D的分数.
BTW: C++ 的版本也是用 thread 的, 性能比D差.
er-lang 的表现不错.
D 的程序记得没有用 fiber, 被人用 thread 去实现的, qiezi 不妨去提交一个 fiber 的版本, 提高D的分数.
BTW: C++ 的版本也是用 thread 的, 性能比D差.
fiber不一定会比thread性能高的,特别是大量计算的只会降低效率。只是更容易生成大量的“线程”,提高并行能力。如果实现erlang这种架构,就可以让程序写起来更方便,用同步的写法就完成了异步的调用,对于库的编写要求会比较高。
上面这个测试程序只是简单测试一下可行性,看有没有人有兴趣一起研究一下,这种架构最主要的难点在于调度,不过这是个不断优化的过程,关键是看有没有简化编程。D的垃圾收集对于委托的影响还没测试到呢,它和fiber的配合程度怎样也不清楚,毕竟fiber的堆栈是要不断切换的,而D的GC在扫描堆栈时只是扫描线程栈。
3 楼
qiezi
2007-09-15
Colorful 写道
听说FP并行有优势,但是俺命令式陷入太深了!
是更容易做成并行,但这也依赖于实现。
2 楼
redsea
2007-09-15
language shootout 那里有个 cheap concurrent 测试, 就是测试类似能力的.
er-lang 的表现不错.
D 的程序记得没有用 fiber, 被人用 thread 去实现的, qiezi 不妨去提交一个 fiber 的版本, 提高D的分数.
BTW: C++ 的版本也是用 thread 的, 性能比D差.
er-lang 的表现不错.
D 的程序记得没有用 fiber, 被人用 thread 去实现的, qiezi 不妨去提交一个 fiber 的版本, 提高D的分数.
BTW: C++ 的版本也是用 thread 的, 性能比D差.
1 楼
Colorful
2007-09-15
听说FP并行有优势,但是俺命令式陷入太深了!
发表评论
-
D语言模板和编译期执行
2012-07-29 00:15 0D语言模板继承了C++模板的基本用法,在其上做了相当多扩充,近 ... -
Generator
2008-04-09 13:46 2019几种并发编程模型开销(从大到小): Process > ... -
lambda之路...
2007-11-09 22:57 2882DMD最近的版本号加入了闭包,感觉非常有用,虽然有些背后动作, ... -
[D语言] qsort的尴尬
2007-05-06 21:31 5092phobos里面在stc.c.stdlib里提供了qsort, ... -
强类型数值计算
2007-04-10 21:45 4731以前曾经讨论过使用typedef来完成强类型的数值计算,最终遇 ... -
简单的单元测试框架
2007-04-10 21:20 3162做了个简单的单元测试框架,只算个毛坯,遇到一些问题。 1、由 ... -
仿STL的vector,写了一组array操作方法。
2007-04-05 23:55 12060文档从MSDN抄过来的,稍稍改了一下。 module ar ... -
编译期执行的效率
2007-03-15 15:58 4244写了一个编译期执行的fibonacci模板: templ ... -
D语言编译期生成和编译期执行技术
2007-02-24 14:35 4140借助D语言新的mixin表达式,可以完成一些代码生成功能,比如 ... -
如何获得一个方法的名字?
2007-01-15 19:24 3501在D语言中,一个方法你可以得到它的指针(函数指针或委托),但不 ... -
D语言的函数编程
2007-01-07 11:17 3874前阵子论坛上有人问我D语言做函数编程怎样,老实说我没怎么想过这 ... -
D语言和python的差异
2007-01-07 10:12 6572这2个语言的比较怪怪的,我最近转换了一些twisted的源文件 ... -
从简单测试看D数组内存分配策略
2007-01-07 09:43 3240D语言动态数组可以在运行期改变大小,这和C++的vector相 ... -
DMD 0.178发布
2006-12-24 15:32 4614What's New for D 0.178 ... -
GDC 0.20发布
2006-12-17 14:35 2818引用 * Updated to DMD 0.177 * Fix ... -
DMD 0.177发布
2006-12-09 18:47 2285没什么亮点,BUG修复得也不多,BUG数量始终保持在250-2 ... -
DMD 0.176发布
2006-12-03 14:22 3087引用 What's New for D 0.176 Dec ... -
D语言的成员函数模板
2006-12-02 20:29 3087DMD 0.166 特性列表中有一条: * ncorp ... -
D语言 在栈上分配对象 以及 无需GC拖管对象
2006-11-28 13:18 2834一、栈上分配对象 C++可以轻易实现在栈上和堆上分配对象,例 ... -
打算把twisted移植到D语言上
2006-11-26 20:14 4223twisted是一个优秀的python网络开发库,以前用它做过 ...
相关推荐
【Erlang程序设计(第2版)】是由Erlang之父Joe Armstrong撰写的一本经典著作,专注于介绍Erlang编程语言在并发、分布式和容错系统中的应用。本书适用于初学者和有一定经验的Erlang程序员。作者在书中讨论了如何利用...
标题中的“用Erlang写了个解八数码的小程序”指的是使用Erlang编程语言实现的一个解决8数码问题(也称为滑动拼图)的算法。8数码问题是一个经典的计算机科学问题,它涉及到在一个3x3的网格上,通过空格与其他数字...
### Erlang与C语言程序接口详解 #### 一、引言 在软件开发领域,不同编程语言之间的交互是一项重要的技术。Erlang作为一种专为构建高并发、容错性强的应用程序而设计的语言,在与其他语言(如C语言)的集成方面具有...
在深入理解Erlang程序设计的源码之前,我们需要了解Erlang的一些核心概念和特性。 1. **并发性**:Erlang的并发模型基于轻量级进程(Lightweight Processes,LWP),它们类似于操作系统中的线程,但资源消耗小得多...
这份"Erlang游戏程序学习完整PDF手册"是一份全面介绍Erlang在游戏开发中应用的学习资料,包含了Erlang的基础知识、并发原理以及在游戏开发中的实践案例。 Erlang语言的设计理念源自于Ericsson公司为解决电信系统中...
Erlang基于函数式编程范式,这意味着程序由纯函数构成,没有副作用。函数式编程强调数据不可变性和函数的数学属性,使代码更易于理解、测试和并行处理。 ### 2. 并发与轻量级进程 Erlang的一大亮点是其内置的并发...
### 编写分布式的Erlang程序:陷阱和对策 #### 摘要与背景 在探讨编写分布式的Erlang程序时,本篇文章聚焦于Erlang编程语言中的分布式特性,尤其是那些容易忽视的陷阱及其对应的解决方案。Erlang作为一种专为构建...
### Erlang语言程序设计 #### 一、Erlang语言简介与重要性 Erlang是一种功能强大且灵活的编程语言,它最初由爱立信公司开发,旨在为电信系统提供高并发、分布式处理能力。随着时间的发展,Erlang不仅在电信领域...
本压缩包文件包含的是 Erlang 连接 MySQL 的源码,这可能是一个 Erlang 驱动程序或应用程序,允许开发者在 Erlang 中编写代码以操作 MySQL 数据库。通常,这样的库会提供接口函数,用于执行 SQL 查询、插入、更新和...
confetti, Erlang配置提供程序/应用程序 纸屑五彩纸屑是你的Erlang应用程序的配置提供程序。基本上是 application:get_env/2 在类固醇上。特性管理控制台可以通过telnet维护部门访问将为你 love在运行时重新加载( ...
递归在Erlang程序设计中占有重要地位,因为Erlang不支持传统的循环结构。理解如何有效地使用递归来解决问题是学习Erlang的一个关键点。 错误和异常处理也是Erlang编程的一个重要部分。由于Erlang的设计哲学是容错,...
Erlang B模型是通信系统设计中一个重要的理论工具,主要用来预测在特定呼叫速率下,多条并行服务通道能够处理的呼叫流量,以及因此产生的呼叫丢失率。这个模型由丹麦数学家Agner Krarup Erlang在20世纪初提出,常...
3. **环境变量**:安装过程中,安装程序可能会自动添加Erlang的bin目录到系统的PATH环境变量中,确保命令行可以识别`erl`等Erlang命令。 4. **验证**:安装完成后,打开命令行窗口并输入`erl`,如果Erlang成功安装,...
在Erlang开发中,rebar是一个非常重要的构建工具,它可以帮助我们管理和编译Erlang应用程序,同时支持发布功能。本文以nitrogen_2.0.4框架为例,详细阐述使用rebar进行Erlang项目开发和发布的全过程。 ### 一、环境...
这两本电子书——《Erlang and OTP in Action》和《Erlang程序设计》——都是深入学习Erlang语言和OTP的宝贵资源。 《Erlang and OTP in Action》这本书主要分为三个部分。第一部分介绍Erlang语言的基础知识,包括...
总而言之,Erlang9.rar是一个包含Erlang/OTP 20.0 Windows 64位安装程序的压缩包,主要用于安装Erlang环境,以支持像RabbitMQ这样的Erlang应用。Erlang以其独特的并发模型和强大的错误恢复能力,广泛应用于需要高...
"Erlang Windows 64位 安装包"指的是针对Windows操作系统64位架构的Erlang二进制安装程序。这个特定的版本是v22.0,名为"esl-erlang_22.0_windows_amd64.exe",由Erlang Solutions Limited(ESL)提供。ESL是一家...
这个压缩包包含了一个基于Erlang B公式的计算器程序,以及其源代码和实验报告,旨在帮助理解和应用这个公式。 Erlang B公式是由丹麦工程师A.K. Erlang提出的,用于预测在一个服务系统(如电话交换机)中有一定数量...
"xiandiao_erlang_Erlang课后习题_"这个压缩包文件包含了Erlang程序设计第二版的课后习题源码,这对于学习和深入理解Erlang编程至关重要。 Erlang的特点: 1. **函数式编程**:Erlang基于函数式编程范式,强调无副...