我刚刚开始学习线程安全性。这让我的代码更具防御性,也许太防守。
使用像Erlang这样的函数式语言会完全摆脱这种担忧吗?
答案 0 :(得分:17)
重点是流程不共享状态,传递消息;线程默认共享所有内容,并且必须进行仲裁以避免混乱。
因此,您不需要线程安全,因为您不使用线程。
答案 1 :(得分:5)
哈维尔是对的。
但是,我想添加之前已经抓住我的东西。如果您正在使用内置驱动程序或nif,它可能不再是线程安全的。似乎很明显,因为驱动程序或nif将使用C或C ++代码,但值得一提。所以你不能完全忽略线程安全只是因为你正在使用Erlang。
答案 2 :(得分:3)
没有。见Erlang Style Actors Are All About Locking。用功能语言实现线程安全要容易得多,但你需要考虑它。
我刚刚开始学习线程安全性。这让我的代码更具防御性,也许过于防守。
请注意,在这种情况下,您很可能仍然会出错。除了大多数琐碎的例子之外,共享 - 所有并发性非常难以正确。
答案 3 :(得分:2)
不,你仍然需要考虑Erlang中的线程安全性,但问题要简单得多解决。
我读过an article,其中作者指出您的消息API可能会导致线程问题。该示例围绕着一个银行账户。他的初始消息API有GET和SET操作。想要存入100美元的一些代码将获得当前值,向其添加100,然后设置结果。当然,这仅适用于单个进程访问银行帐户的情况。一旦两个进程操纵平衡,所有投注都将被取消。
他的解决方案是将消息API更改为DEPOSIT和WITHDRAW(他实际上使用了一条消息 - 更新 - 但你明白了)。这导致交互假设原子语义 - 监听过程一次只处理一次存款或取款,并将阻止其他请求直到第一次完成。
值得注意的是,此问题与共享内存问题基本相同。 (如果我们使用GET和SET消息与进程交互,我们基本上创建了一些共享内存)。另一位博主compares ets to shared memory也是。但是,只要您了解在何处引入了类似共享内存的构造并规范对该共享内存的访问,您就不应该遇到任何线程问题(当然除了死锁之外)。
答案 4 :(得分:1)
免责声明:我几乎不知道Erlang。用我的意见侃侃而谈。
纯粹的功能性语言(显然)只允许“纯粹”的功能。 Wiki说纯函数总是线程安全的,因此证实了我对该主题的直觉。
但是我不知道Erlang是否纯粹是功能性的(wiki暗示其他方面,所以我猜它不是)。也许它使用其他方法来实现线程安全。无论如何,它的数据结构(主要是?排他?)是不可变的,因此本质上是线程安全的。作为一种函数式语言,至少惯用的Erlang代码不会使用(muc?any?)全局变量,而是使用纯函数。这些是线程安全的。但事情I / O可能仍然是一个问题...如果Erlang程序同时读取和写入文件,这样的代码可能不是线程安全的。但大多数时候,由于不可变的数据结构等等,你会没事的。