线程中未封闭的ZeroMQ套接字

时间:2014-05-09 22:22:26

标签: multithreading haskell zeromq

如果进程线程打开inproc ZMQ套接字,然后由于某些未处理的异常而死亡,那么如果套接字未关闭会发生什么?这种做法有多糟糕?

更具体地说,我在Haskell中实现了一个非常类似于http://zguide.zeromq.org/page:all#Multithreading-with-MQ的非常简单的消息代理。

工作线程打开一个新套接字,并在无限循环中等待处理消息。 套接字未在工作线程中的任何位置关闭。

现在,如果工作线程中存在未处理的异常,并且线程死亡,那么在没有关心的情况下重新启动线程有多糟糕?

我正在粘贴Haskell示例中的worker代码:

worker :: ZMQ z ()
worker = do
    receiver <- socket Rep
    connect receiver "inproc://workers"
    forever $ do
        receive receiver >>= liftIO . printf "Received request:%s\n" . unpack    
        -- Suppose there is some exception here
        liftIO $ threadDelay (1 * 1000 * 1000)  
        send receiver [] "World"

1 个答案:

答案 0 :(得分:1)

所以看来如果你不关闭inproc套接字,重新启动的线程就不能很好地接受消息。我不确定我是否理解这种行为,但我可以确认ZMQ haskell指南中的这个修改示例有效:

import System.ZMQ3.Monadic
import Prelude hiding (catch)
import Control.Monad.CatchIO

worker :: ZMQ z ()
worker = do
            liftIO $ putStrLn "Starting the worker thread..."
            receiver <- socket Rep 
            connect receiver "inproc://workers"
            catch
                (forever $ do
                    liftIO $ putStrLn "Waiting for an inproc message" 
                    request <- receiveMulti receiver -- request :: ByteString.Char8
                    liftIO $ putStrLn "I'm doing something that may throw an error"
                    -- error "IO Error has happened"
                )   
                (\(e :: IOError) -> do
                    liftIO $ putStrLn $ "Caught error: " ++ (show e)
                    close receiver -- Commenting this out will result in the restarted worker thread being unable to accept new messages                                                                                               
                )