2014-07-26 14 views
7

olmamalıdır bir durumda deadlocked oluyor Aşağıdaki, bir kilitlenme hata iletisi verir (* İstisna: iş parçacığı bir MVar işleminde süresiz olarak engellenir). Adım adım düşündüm ve sorunu göremiyorum.Haskell (teoride)

ana iş parçacığı üzerinde
  • , bir MVAr ana iş parçacığı içine devam eden bir bağlantı
  • bekliyor, yeni bir iş parçacığı üzerinde ListenOn de
  • yapımcı başlar ve bloklar çalışan oluşturulur ve üreticiye verilir döngü ve bloklar, yapımcı bağlantı alır almaz bir şey
  • almayı Mvar bekliyor (, onu en döngüye devam eder ve soket bir şey aldıktan sonra, MVAr

Anlamı içine koyar bunu anladığım kadarıyla, MVar'a bir şey koyarak ve bir şey almak için bekleyen ana yapımcı ile sonuçlanmalı.

Eğer sıkışıyorsa, dinlemenin hemen bağlanmasına izin verilmiyor, bunun için nasıl geçebilirim? girişimleri kullanmak veya ondan okumak çok, MVAr ana oluşturulacak gerekiyor ve yapımcı böylece çatallı önce içeri geçirilebilir.

import Control.Concurrent 

import Network 
import Network.Socket 

import System.IO 

getSockInfo :: Socket -> IO String 
getSockInfo s = do 
     info <- getPeerName s 
     return $ case info of 
      (SockAddrInet port addr) -> "Addr/Port: " ++ (show addr) ++ "/" ++ (show port) 
      (SockAddrInet6 port flow addr scope) -> 
       "Addr/Port: " ++ (show addr) ++ "/" ++ (show port) ++ "Flow/Scope: " ++ (show flow) ++ "/" ++ (show scope) 

producer :: MVar String -> IO() 
producer m = do 
    s <- listenOn (PortNumber 5555) 
    putStrLn "Listening..." 
    info <- getSockInfo s 
    putStrLn $ "Connected to " ++ info 
    h <- socketToHandle s ReadMode 
    loop h m 
    where loop h m = do 
     message <- hGetLine h 
     putMVar m message 
     loop h m 

main :: IO() 
main = do 
    withSocketsDo $ do 
     m <- newEmptyMVar 
     prod <- forkIO $ producer m 
     loop m 
     where loop m = do 
      n <- takeMVar m 
      print n 
      loop m 
+0

Bina ile mi çalışıyorsunuz? –

+0

@Ganesh No. Bu, yalnızca sendTo/receiveFrom'un davranışını değiştirmez mi? – Carcigenicate

+0

Emin değilim, ama bir eşzamanlılık sorunu yaşadığımda kontrol ettiğim ilk şey. Yine de bu durumda bir fark yaratmıyor gibi görünüyor. –

cevap

4

listenOn döner derhal ama size bağlı yuvasıyla vermez başarısız. Kodunuzu çalıştırdığımda neden yaptığımı gösteren bir hata mesajı görmediğinizden emin değilim. Her durumda, dinleme ipliği muhtemelen o noktada ölmekte olup, bu da ana parçacığın kilitlenmesini engeller, çünkü MVar'a hiçbir şey yazamaz.

listenOnaccept kullanıldıktan sonra uzak bir bağlantı için beklemeniz gerekir.

+0

Teşekkürler bayım. Neden bir bağlantı hatası yerine neden kilitlenme hatası alıyorum anlamıyorum. Bağlantı problemini mvardan önce fark edeceğini düşünürsünüz (bu tembelliğin bir ürünü olmadığı sürece).Sistem genelinde tutarlı olacağını düşünebilirsiniz) – Carcigenicate

+0

Muhtemelen dinleyeni dinleyeni bir istisna ile ölür, ancak bu istisnayı ana iş parçacığına yaymazsanız, onu asla göremezsiniz. Konularınızı oluşturmak için 'async' paketini kullanmanızı öneriyorum. Sizin için istisna güvenliği ve yayılma istisnaları gibi şeyleri ele alacaktır. – tibbe

+0

Soruda kodu çalıştırdığımda konsolda yazdırılan istisnayı gördüm, ancak OP farklı bir derleyici veya benzer kullanıyor. –