Multithreading 在Windows上是否可以不终止等待Network.Socket.accept的Haskell或Haskell OS线程?

Multithreading 在Windows上是否可以不终止等待Network.Socket.accept的Haskell或Haskell OS线程?,multithreading,exception,networking,haskell,asynchronous,Multithreading,Exception,Networking,Haskell,Asynchronous,可以在Linux上工作(可能也可以在OSX和FreeBSD上工作),但不能在Windows上工作(使用+RTS-N4-RTS等尝试线程化) 在这种情况下,终止线程A的正确方法是什么 是否有一种方法可以在特殊模式下分叉线程a,从而允许在其阻塞点处终止接受 如果用forkOS而不是forkIO来分叉A会有帮助吗 只有当一个有趣的问题提醒我时,我才注意到这种异常的Windows行为。有趣的问题 你不能中断阻止外呼,所以我有点惊讶你能在Linux上中断线程。而且,forkOS也没有帮助——它只允许外

可以在Linux上工作(可能也可以在OSX和FreeBSD上工作),但不能在Windows上工作(使用+RTS-N4-RTS等尝试线程化)

  • 在这种情况下,终止线程
    A
    的正确方法是什么
  • 是否有一种方法可以在特殊模式下分叉线程
    a
    ,从而允许在其阻塞点处终止
    接受
  • 如果用
    forkOS
    而不是
    forkIO
    来分叉
    A
    会有帮助吗
只有当一个有趣的问题提醒我时,我才注意到这种异常的Windows行为。

有趣的问题

你不能中断阻止外呼,所以我有点惊讶你能在Linux上中断线程。而且,
forkOS
也没有帮助——它只允许外部代码分配线程本地存储,而与阻塞行为无关。但请记住,accept可以设置为非阻塞:

如果队列上不存在挂起的连接,并且套接字 accept()未标记为非阻塞,它会阻塞调用方,直到 连接已存在。如果插座标记为非阻塞和否 队列上存在挂起的连接,accept()失败,错误为 EAGAIN或EWOOLDLOCK错误

这就是所做的,然后允许中断
accept

关于Windows的有趣说明:

-- thread B
killThread t
现在,Windows上的accept和-threaded运行时使用accept_-safe(它允许其他线程取得进展)——但它不会将套接字置于非阻塞模式:

-- 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.
accept sock@(MkSocket s系列stype协议状态)=do

当前状态相关:哇!!感谢你的代码,除了我找到了一个很好的快速修复。我看到在非线程运行时,他们正在执行
asyncDoProc
调用,这些调用可能会被中断:)所以在Windows上,我将默认使用该运行时,直到找到更好的解决方案。是的,我们需要在默认情况下为Windows启用非阻塞接受。在这种特殊情况下,我还将确认并发布我是否真的可以在Linux上中断
accept
。我刚刚检查并确认
accept
在Linux上是可中断的(OS X和FreeBSD可能与Linux相同)。
-- 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.
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