为何在函数中通过putTMVar填充的TMVar在调用函数中不可见?
为什么写入TMVar后读取时它还是空的?
我一眼就揪出问题所在了——你定义Hook记录时,把hookResult设成了newEmptyTMVarIO,这是一个IO动作,而非TMVar实例本身!
问题核心原因
每次访问hookResult这个字段时,它都会重新执行newEmptyTMVarIO,生成一个全新的空TMVar。简单说就是:
- 在
executeHook里,你调用hr <- hookResult拿到的是某个TMVar,写入了结果; - 回到
lockExecuteHook里调用hr <- hookResult时,你拿到的是另一个完全独立的空TMVar。这就是为什么调试日志里明明显示写入后TMVar非空,读取时却还是空的——你从头到尾操作的根本不是同一个变量!
解决方案
你需要把记录里的hookResult类型从IO (TMVar o)改成TMVar o,初始化时先执行IO动作拿到实例,再放进记录里:
- 修改Hook初始化代码:
hook <- do resultVar <- newEmptyTMVarIO pure Hook { -- 其他属性保持不变 hookResult = resultVar }
- 调整记录类型定义:
把hookResult的类型从IO (TMVar o)改为TMVar o,这样所有地方访问这个字段时,拿到的都是同一个TMVar实例。
对应你的调试日志解释
你看到的HOOK RESULT PUT EMPTY AFTER: False是第一个TMVar的状态,而READING HOOK !!!!!!!!!!!!!!!!!!!!!!!!!! EMPTY: True是第二个全新空TMVar的状态——这俩完全是不同的变量,所以写入操作根本没影响到你要读取的那个TMVar,自然会阻塞在readTMVar上。
内容的提问来源于stack exchange,提问作者John Walker
相关产品推荐
相关产品推荐

