多线程 – 可以在Windows上等待Network.Socket.accept的Haskell
-- thread A t <- forkIO $do _ <- accept listener -- blocks -- thread B killThread t 在Linux上(可能也在OS X和FreeBSD上),但不在Windows上(使用RTS -N4 -RTS等等). >在这种情况下终止线程A的正确方法是什么? 我注意到这个错误的Windows行为只有当一个bug report警告. 解决方法
有趣的问题!
你不能中断阻止外来电话,所以我有点惊讶,你可以在Linux上中断线程.而且,forkOS没有帮助 – 只允许外部代码分配线程本地存储,但与阻止行为无关.但是回想一下接受可以设置为无阻塞:
这是做什么in the Network library for Posix systems.这样就允许接受中断. 关于Windows的一个有趣的注释: -- On Windows,our sockets are not put in non-blocking mode (non-blocking -- is not supported for regular file descriptors on Windows,and it would -- be a pain to support it only for sockets). So there are two cases: -- -- - the threaded RTS uses safe calls for socket operations to get -- non-blocking I/O,just like the rest of the I/O library -- -- - with the non-threaded RTS,only some operations on sockets will be -- non-blocking. Reads and writes go through the normal async I/O -- system. accept() uses asyncDoProc so is non-blocking. A handful -- of others (recvFrom,sendFd,recvFd) will block all threads - if this -- is a problem,-threaded is the workaround. 现在,在Windows上接受运行时的线程,使用accept_safe(允许其他线程进行) – 但是它不会将套接字置于非阻塞模式: accept sock@(MkSocket s family stype protocol status) = do currentStatus <- readMVar status okay <- sIsAcceptable sock if not okay then ioError (userError ("accept: can't perform accept on socket (" ++ (show (family,stype,protocol)) ++") in status " ++ show currentStatus)) else do let sz = sizeOfSockAddrByFamily family allocaBytes sz $ sockaddr -> do #if defined(mingw32_HOST_OS) && defined(__GLASGOW_HASKELL__) new_sock <- if threaded then with (fromIntegral sz) $ ptr_len -> throwErrnoIfMinus1Retry "Network.Socket.accept" $ c_accept_safe s sockaddr ptr_len else do paramData <- c_newAcceptParams s (fromIntegral sz) sockaddr rc <- asyncDoProc c_acceptDoProc paramData new_sock <- c_acceptNewSock paramData c_free paramData when (rc /= 0) (ioError (errnoToIOError "Network.Socket.accept" (Errno (fromIntegral rc)) Nothing Nothing)) return new_sock 自2005年以来,在Windows上使用-threaded的版本显式地使用了一个标记为安全的接受调用,允许其他线程取得进展,但不将套接字本身设置为非阻塞模式(因此调用线程阻塞). 要解决它,我看到两个选项: >制定如何在Windows上进行非阻塞接受呼叫,并修补网络库 – 查看例如snap或yesod在这里,看看他们是否已经解决了.>使用某种监控线程伪造epoll,监控被阻止的子线程进度. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |