我正在为 C 中的库创建一个 FFI 模块,该模块希望在执行其他操作之前调用一个一次性、不可重入的函数。这个调用是幂等的,但是有状态的,所以我可以在每个 Haskell 调用中调用它。但它很慢,并且由于不可重入,可能会导致冲突。
那么现在是使用 unsafePerformIO 的合适时机吗?我可以将 Bool 包装在不安全的 IORef 或 MVar 中,通过忽略后续调用(全局隐藏 IORef 状态为 False 的调用)来使这些初始化调用具有幂等性。
如果不是,那么正确的方法是什么?
我更喜欢初始化一次并提供不可伪造的令牌作为您已初始化机器的证据的方法。
所以你的证据将是:
data Token = Token
您抽象地导出它。
然后你的初始化函数可以返回这个证据。
init :: IO Token
现在,您需要将该证明传递给您的 API:
bar :: Token -> IO Int
bar !tok = c_call_bar
etc.
您现在可以用 monad 或一些更高阶的初始化环境将这些东西包装起来,以使其更清晰,但这就是基本思想。
使用隐藏状态初始化 C 库的问题是,您最终要么无法并行访问库,要么在 GHCi 中出现问题,混合编译和字节码,加载两个不同版本的 C 库(这将失败)链接器错误)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)