在Erlang中,gen_server:start()和gen_server:start_link()有什么区别?

12
有人可以解释一下 gen_server:start()gen_server:start_link() 之间的区别吗?我被告知这涉及到多线程问题。
编辑:如果我的 gen_server 被多个线程调用,它会同时执行它们吗?还是会在这些线程之间创建并发性?
2个回答

13

这两个函数都会启动新的gen_server实例作为调用进程的子进程,但它们的区别在于 gen_server:start_link/3,4 原子性地启动一个gen_server子进程并将其与父进程进行链接。链接意味着如果子进程死亡,则默认情况下父进程也会死亡。 监管者是使用链接的父进程,以在其子进程异常退出时执行特定操作,通常是重启它们。

除了gen_server:start_link中涉及的链接外,这些调用没有涉及多进程方面。无论您是使用gen_server:start还是gen_server:start_link来启动新的gen_server,新进程都有一个消息队列,并且逐个接收和处理这些消息。 gen_server:start_link并没有导致新的gen_server进程表现或执行与使用gen_server:start启动时有所不同的任何事情。


1
我已经回答了你编辑中的内容。如果多个进程并发调用您的gen_server,它们的消息将排队在gen_server消息队列中,然后gen_server一个接一个地处理这些消息。 - Steve Vinoski

5
当你使用gen_server:start_link时,新的进程将成为调用进程的“子进程” - 它是监督树的一部分。如果gen_server进程死亡,它允许调用进程被通知。
使用gen_server:start会在监督树之外生成进程。
Erlang中有一个关于监督的很好的描述,链接在这里:http://learnyousomeerlang.com/supervisors

如果我的 genserver 从多个线程调用,它会同时执行它们吗?还是会在这些线程之间创建并发性? - Guga Melkadze
谢谢你的回答,你能回答我这个问题吗? - Guga Melkadze
4
Erlang并不使用术语“线程”,而是称之为“进程”。如果多个进程调用同一个gen_server,则它们的请求将被放入队列中,一个接一个地处理。在http://learnyousomeerlang.com/content上有一个非常好的OTP部分。 - Novakov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接