Ошибка выполнения с привязкой 0MQ Haskell: getIntOpt: прервано (прерванный системный вызов)

Приведенная ниже функция основана на привязках 0MQ Haskell. Я получаю ошибку во время выполнения. Ошибка говорит getIntOpt: interrupted (Interrupted system call) и программа останавливается.

Вероятно, это связано с параметрами командной строки, которые я использую, а затем отбрасываю из-за критерия?

Изменить: обнаружил, что я получаю сообщение об ошибке также, когда оставляю свой собственный код без cmdArgs. На самом деле существует гораздо более интересная проблема. См. последний абзац здесь. Но я до сих пор понятия не имею, как с этим эффективно бороться.

    sendReceive :: B.ByteString -> IO ()
    sendReceive datastring = withContext 1 $ \context -> do
         withSocket context Req $ \requester -> do
            --putStrLn "Connecting ..."
            connect requester "tcp://192.168.35.84:5559"
            let tryOnePing (!c, !f) i = do
                send requester datastring []
                --putStrLn "Sent ..."
                r <- receive requester []
                --putStrLn "Received ..."
                return $ case B.unpack r of
                   datastring -> (c+1, f)
                   _ -> (c, f+1)
            (c,f) <- foldM tryOnePing (0,0) [1 .. 1000]
            -- c and f are not used in this example
            return ()

main = do
     n <- cmdArgsRun strlen
     let datastring  = B.pack (take (byte n) $ randomRs ('a','z') (mkStdGen 3))
     putStrLn "Starting..."
     withArgs [] $ defaultMain [bench "sendReceive" $ whnfIO (sendReceive datastring)]

person J Fritsch    schedule 10.12.2011    source источник


Ответы (1)


Привязки используют вспомогательную функцию FFI throwErrnoIfMinus1_, которая выдает ошибку из errno, если обернутая функция возвращает -1. Новая библиотека zeromq ожидает, что вызывающий объект правильно обработает EINTR, чего здесь не происходит.

Вы можете попросить сопровождающего библиотеки использовать throwErrnoIfMinus1Retry_, который автоматически повторяет обернутую функцию, если она возвращает -1, а errno установлено на EINTR.

Похоже, вы можете поймать IOException, но я не знаю, как получить значение errno, даже если оно хранится в нем (если только вы не хотите импортировать GHC.IO.Exception, что мне кажется сомнительным).

person Antoine Latter    schedule 10.12.2011
comment
Спасибо. Могу ли я исправить здесь что-то с throw или catch отсюда: haskell.org/ghc/docs/6.12.1/html/libraries/base/ ?? - person J Fritsch; 10.12.2011
comment
Вы можете поймать IOException, но я не смог найти стандартный способ получить из него значение errno без импорта GHC.IO.Exception — вы бы не хотели повторять действие автоматически, если errno не было EINTR. - person Antoine Latter; 11.12.2011
comment
К плохому. При высоких частотах обмена сообщениями это происходит довольно часто. В конце концов это может сделать всю привязку Haskell бесполезной для реальных приложений. - person J Fritsch; 11.12.2011
comment
Нетрудно исправить привязку: github.com/twittner/zeromq-haskell Я рекомендую попробовать, чтобы убедиться, что мое предложение было правильным :-) - person Antoine Latter; 11.12.2011
comment
Или, как минимум, вы можете сообщить об ошибке мейнтейнеру, чтобы мейнтейнер знал, что есть что исправить. - person Antoine Latter; 11.12.2011