2013-06-05 4 views
5

थ्रेड किए जाने पर धीमी सॉकेट कनेक्शन मैंने कुछ समय पहले हास्केल से शुरुआत की है और अब मैं नेटवर्किंग पर ध्यान केंद्रित कर रहा हूं। मैं एक साथ एक बहुत ही सरल गूंज सर्वर लगाने के लिए कुछ ट्यूटोरियल और स्रोत के नमूने का पालन किया: अबहास्केल -

main = withSocketsDo $ do 
    forkIO $ acceptor 8080  
    print "Server running ... " >> getLine >>= print 


tcpSock :: IO Socket 
tcpSock = socket AF_INET Stream 0 

acceptor :: PortNumber -> IO() 
acceptor port = do 

    -- Setup server socket 
    sock <- tcpSock 
    setSocketOption sock ReuseAddr 1 
    bindSocket sock (SockAddrInet port iNADDR_ANY) 
    listen sock 50 

    -- Start with zero index 
    loop sock 0 
     where 
     loop sock sockId = do 
      -- Accept socket 
      (nextSock, addr) <- accept sock 

      -- Setup the socket for performance 
      (_, handle) <- setupClient nextSock 

      -- Run client in own thread 
      forkIO $ do 
       -- Get a stream of bytes 
       stream <- BS.hGetContents handle 

       -- Echo the first received char 
       BS.hPut handle $ BS.take 1 stream 

       -- Kill the socket 
       SIO.hClose handle 


      -- Accept next client 
      loop sock (sockId + 1) 


setupClient :: Socket -> IO (Socket, SIO.Handle) 
setupClient sock = do 
     -- Disable nagle 
     setSocketOption sock NoDelay 1 

     -- Disable buffering 
     hdl <- socketToHandle sock SIO.ReadWriteMode 
     SIO.hSetBuffering hdl SIO.NoBuffering 

     return (sock, hdl) 

, मैं बेंचमार्क अब-उपकरण सर्वर के साथ कोड परीक्षण किया है। कोड को संकलित किया गया है -ओ 2 और -थ्रेड किया गया है और प्रोग्राम कई ओएस थ्रेड का उपयोग करने के लिए + आरटीएस-एन का उपयोग शुरू कर दिया गया है।

कोड प्रति क्लाइंट एक नया हल्का धागा बनाता है और जहां तक ​​मुझे याद है कि ये धागे बहुत सस्ते हैं क्योंकि वे वास्तविक ओएस धागे के समूह द्वारा निर्धारित हैं।

उपकरण चलाने के बाद, परिणाम हैं:

अब -n 10000 -c 1000 http://localhost:8080/ ~ 500 - 1600 अनुरोध/सेकंड हाँ, यह कभी कभी 500 और 1600 के बीच परिवर्तित करता है!

पहले मैंने सोचा, बुरा नहीं। फिर मैंने "+ आरटीएस-एन" के बिना कार्यक्रम चलाया और परिणाम लगभग हर समय ~ 20000 req/sec हैं।

स्पष्ट रूप से थ्रेडिंग प्रदर्शन को बहुत खराब तरीके से मारता है, लेकिन क्यों? मेरा अनुमान है कि आईओ मैनेजर बहुत सारे कनेक्शन से निपटने के दौरान एक बहुत ही खराब काम करता है।

बीटीडब्लू: मैं उबंटू 13.04 और ghc 7.6 का उपयोग करता हूं, लेकिन मैंने विंडोज 8 के तहत कोड का परीक्षण किया है जिसने मुझे बहुत खराब परिणाम दिए हैं, लेकिन मुझे लगता है कि आईओ मैनेजर लिनक्स के लिए ट्यून किया गया है, जो समझ में आता है।

क्या मैं यहाँ कुछ बेवकूफ बेवकूफ कर रहा हूं ?? मुझे पता है, उदाहरण काफी छोटा है लेकिन यहां स्पष्ट रूप से कुछ गलत हो रहा है।

सादर, क्रिस

+0

है कि 20 या 20000 20.000 में – Satvik

+0

यह 20000, गलतफहमी – Kr0e

+0

कितने वास्तविक धागे करता है आपके प्रोसेसर है और आप कितने वास्तविक धागे का उपयोग कर रहे (तर्क एन करने के लिए) – Satvik

उत्तर

1

ठीक है, मुझे लगता है कि मैं इस समस्या अर्द्ध हल, हालांकि मैं अभी भी यकीन है कि जहां त्रुटि है नहीं कर रहा हूँ/था।

अब मैं नेटवर्क पैकेज का उपयोग कर रहा हूं, इसलिए स्वीकृति दिनचर्या हैंडल-आधारित है। मैंने कोशिश की क्योंकि मैंने कुछ परीक्षणों के बाद मेमोरी रिसाव देखा।

इस तरह मैंने एक बार में दो समस्याएं हल की, क्योंकि अब थ्रेडिंग कोई फर्क नहीं पड़ता। मैं वास्तव में नहीं जानता कि यह क्यों हो रहा है, लेकिन हैंडल-आधारित इम्प्ल्यू। सरल और स्पष्ट रूप से तेज़/अधिक सुरक्षित है।

शायद यह अन्य लोगों को एक ही समस्या का सामना करने में मदद करता है।

+1

समान रूप से आपका कोड कैसा दिखता है? – chespinoza