2012-05-15 3 views
9
-- thread A 
t <- forkIO $ do 
    _ <- accept listener -- blocks 

-- thread B 
killThread t 

(ओएस एक्स और FreeBSD पर शायद भी), लेकिन पर नहीं विंडोज लिनक्स पर काम करता है (साथ + आरटीएस -N4 -RTS आदि -threaded की कोशिश की)।क्या होस्केल या हास्केल ओएस थ्रेड नेटवर्क पर इंतजार कर सकता है। सॉकेट.एसेप्ट विंडोज पर नहीं मारा जा सकता है?

  • इस मामले में थ्रेड A को समाप्त करने का सही तरीका क्या है?
  • क्या एक विशेष मोड में फोर्क थ्रेड A का कोई तरीका है जो accept पर उस बिंदु पर समाप्ति की अनुमति देगा?
  • के बजाय forkOS के साथ फोर्क किया गया था तो यह मदद करेगा?

मैंने bug report द्वारा सतर्क होने पर केवल इस भयानक विंडोज व्यवहार को देखा।

+2

संबंधित: http://stackoverflow.com/questions/6185189/howto-kill-a-thread-in-haskell –

उत्तर

13

दिलचस्प सवाल!

आप विदेशी कॉल अवरुद्ध करने में बाधा नहीं डाल सकते हैं, इसलिए मुझे कुछ आश्चर्य है कि आप लिनक्स पर धागे को बाधित करने में सक्षम हैं। इसके अलावा, forkOS मदद नहीं करता है - जो सिर्फ विदेशी कोड को थ्रेड-स्थानीय स्टोरेज आवंटित करने देता है, लेकिन इसमें अवरोध व्यवहार से कोई लेना देना नहीं है। लेकिन याद स्वीकार करते हैं कि nonblocking करने के लिए सेट किया जा सकता है:

कोई लंबित कनेक्शन कतार पर मौजूद हैं, और सॉकेट nonblocking के रूप में चिह्नित नहीं है, तो स्वीकार करते हैं() ब्लॉक फोन करने वाले जब तक एक कनेक्शन मौजूद नहीं । यदि सॉकेट को अनब्लॉकिंग चिह्नित किया गया है और लंबित कनेक्शन कतार पर मौजूद हैं, तो स्वीकार करें() त्रुटि EAGAIN या EWOULDBLOCK में विफल रहता है।

है कौन क्या in the Network library for Posix systems. यह किया जाता है तो अनुमति देता है accept बाधित किया।

एक विंडोज के बारे में दिलचस्प ध्यान दें:

-- 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. 

अब,, विंडोज पर स्वीकार -threaded क्रम के साथ, accept_safe (जो अन्य धागे प्रगति करने के लिए अनुमति देता है) का उपयोग करता है - लेकिन यह सॉकेट डाल नहीं है गैर अवरुद्ध मोड में:

accept [email protected](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 के बाद से, network पैकेज के संस्करणों, -threaded के साथ Windows पर स्पष्ट रूप से स्वीकार कॉल safe के रूप में चिह्नित उपयोग करते हैं, अन्य थ्रेड प्रगति करने के लिए अनुमति देता है, लेकिन में सॉकेट खुद की स्थापना नहींगैर-अवरुद्ध मोड (इसलिए कॉलिंग थ्रेड ब्लॉक)।

यह हल करने के लिए मैं दो विकल्प देखेंगे:

  • काम से बाहर कैसे विंडोज पर एक गैर अवरुद्ध स्वीकार कॉल करने के लिए, और नेटवर्क पुस्तकालय पैच - क्या जैसे को देखो स्नैप या हाँोड यहां देखें, यह देखने के लिए कि क्या उन्होंने इसे हल कर लिया है या नहीं।
  • नकली एपोल के लिए किसी प्रकार का पर्यवेक्षी धागा का उपयोग करें, प्रगति के लिए अवरुद्ध बाल धागे की निगरानी करें।
+0

* वाह !! * अपने कोड को छोड़कर मैं एक अच्छा त्वरित सुधार पाया धन्यवाद। मैंने देखा कि गैर-थ्रेडेड रनटाइम के साथ वे 'asyncDoProc' कॉल कर रहे हैं और इन्हें बाधित किया जा सकता है :) तो विंडोज़ पर मैं केवल उस रनटाइम पर डिफ़ॉल्ट होगा जब तक कि मैं एक बेहतर समाधान नहीं समझता। –

+1

हाँ, हमें विंडोज़ के लिए डिफ़ॉल्ट रूप से गैर-अवरुद्ध स्वीकृति प्राप्त करने की आवश्यकता है। –

+0

मैं यह भी पुष्टि करूंगा और पोस्ट करूंगा कि क्या मैं वास्तव में इस विशेष मामले में लिनक्स पर 'स्वीकार' को बाधित कर सकता हूं। –

संबंधित मुद्दे

 संबंधित मुद्दे