多线程 – 可以在Windows上等待Network.Socket.accept的Haskell或Haskell OS线程吗?

前端之家收集整理的这篇文章主要介绍了多线程 – 可以在Windows上等待Network.Socket.accept的Haskell或Haskell OS线程吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
-- thread A
t <- forkIO $do
   _ <- accept listener -- blocks
-- thread B
killThread t

在Linux上(可能也在OS X和FreeBSD上),但不在Windows上(使用RTS -N4 -RTS等等).

>在这种情况下终止线程A的正确方法是什么?
>有没有一种方式来将线程A分叉到一个特殊的模式,允许终止在它阻止接受的点?
>如果A用forkOS而不是forkIO分叉,会有帮助吗?

我注意到这个错误的Windows行为只有当一个bug report警告.

解决方法

有趣的问题!

你不能中断阻止外来电话,所以我有点惊讶,你可以在Linux上中断线程.而且,forkOS没有帮助 – 只允许外部代码分配线程本地存储,但与阻止行为无关.但是回想一下接受可以设置为无阻塞:

If no pending connections are present on the queue,and the socket is
not marked as nonblocking,accept() blocks the caller until a
connection is present. If the socket is marked nonblocking and no
pending connections are present on the queue,accept() fails with the
error EAGAIN or EWOULDBLOCK.

这是做什么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,监控被阻止的子线程进度.

原文链接:https://www.f2er.com/java/122352.html

猜你在找的Java相关文章