什么时候“Data.Unique”线程安全?

When is `Data.Unique` thread safe?

Data.Uniqueuses IORef as the counter that stores the next unique integer.

的内部实现

据我所知,IORefs 并不完全是线程安全的。特别是,在这种情况下,我们需要以原子方式取出数据并向其中添加一个。如果它不是原子的,我们可能会在更新计数器之前读取两个相同的数字。

我知道 newUnique 的实现使用 atomicModifyIORef,据说是原子的 only when one IORef is used in the whole program

因此,如果我在我的程序中不使用任何 IORef,我可以推断 Unique 将是线程安全的。问题是:当我使用另一个 IORef 时会发生什么?行为会有什么问题?或者只有当我尝试在其他 IORef 上使用 atomicModifyIORef 时才会出现问题?

您 link 的 atomicModifyIORef 文档读取:

This function is useful for using IORef in a safe way in a multithreaded program. If you only have one IORef, then using atomicModifyIORef to access and modify it will prevent race conditions.

Extending the atomicity to multiple IORefs is problematic, so it is recommended that if you need to do anything more complicated then using MVar instead is a good idea.

这并不是说如果您的程序包含多个 IORef 就会不安全。它是说您不能 运行 多个 IORef 上的单个原子事务。由于 Data.Unique 一次只关心一个 IORef,从不关心多个 IORef 之间的关系,因此将 Data.Unique 与其他 IORef 结合使用不会出现竞争条件。