多线程 – 可以在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,监控被阻止的子线程进度.

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...