【发布时间】:2015-02-03 08:19:14
【问题描述】:
为什么c_sleep在下面的代码中立即返回?
{-# LANGUAGE ForeignFunctionInterface #-}
import Foreign.C.Types
import Data.Time.Clock
import Control.Concurrent
foreign import ccall unsafe "unistd.h sleep"
c_sleep :: CUInt -> IO CUInt
main :: IO ()
main = do
getCurrentTime >>= print . utctDayTime
c_sleep 10 >>= print -- this doesn't sleep
getCurrentTime >>= print . utctDayTime
threadDelay $ 10 * 1000 * 1000 -- this does sleep
getCurrentTime >>= print . utctDayTime
$ ghc --make Sleep.hs && ./Sleep [1 of 1] 编译 Main ( Sleep.hs, Sleep.o ) 连接睡眠... 29448.191603s 10 29448.20158s 29458.211402s $ ghc --版本 Glorious Glasgow Haskell 编译系统,版本 7.8.3 $ cabal --版本 cabal 安装版本 1.20.0.3 使用 Cabal 库的 1.20.0.0 版本
注意:实际上,我想在 C 代码中使用 sleep 来模拟函数 func 中的一些繁重计算,并在 Haskell 中调用 that 函数,但这也不起作用,可能出于相同的原因。
【问题讨论】:
-
GHC 运行时使用的信号可能会破坏
sleep。你检查过错误代码吗?也许你应该将它包装在一个循环中以在它被中断时重新启动它(在这种情况下,最好使用nanosleep以获得更高的精度)。 -
@Rufflewind:
sleep不返回错误代码,而是以秒为单位的未睡眠量:/。还没试过nanosleep,但是usleep也不管用。 -
错误代码通过
errno变量“返回”。将(c_sleep 10)包裹在throwErrnoIf (/= 0) "sleep"中,您会看到它被中断了。 -
另见this bug。与这个问题不完全相关,但它确实说 RTS,即使是单线程的,也会定期发送信号,这将中断任何
sleep调用。 -
@Rufflewind:谢谢。天哪,为什么
man 3 sleep没有提到errno更新?我想我也会写一个void nanosleep_loop(uint32_t),因为nanosleep也会受到影响。这张票可能回答了这个问题,所以请随意添加。