मैं एक हैकेल नेटवर्क एप्लिकेशन पर काम कर रहा हूं और मैं मल्टीथ्रेडिंग को प्रबंधित करने के लिए अभिनेता पैटर्न का उपयोग करता हूं। एक चीज जो मैंने पार की थी, उदाहरण के लिए क्लाइंट सॉकेट/हैंडल का एक सेट कैसे स्टोर करना है। निश्चित रूप से सभी धागे के लिए सुलभ होना चाहिए और जब ग्राहक लॉग ऑन/ऑफ करते हैं तो बदल सकते हैं।हास्केल - अभिनेता आधारित उत्परिवर्तन
जब से मैं जरूरी दुनिया से आ रहा हूँ मैं ताला तंत्र के कुछ प्रकार के बारे में सोचा, लेकिन जब मैंने देखा कि यह कैसे बदसूरत मैं के बारे में "शुद्ध" अस्थिरता सोचा है, अच्छी तरह से वास्तव में यह एक तरह से शुद्ध है:
import Control.Concurrent
import Control.Monad
import Network
import System.IO
import Data.List
import Data.Maybe
import System.Environment
import Control.Exception
newStorage :: (Eq a, Show a) => IO (Chan (String, Maybe (Chan [a]), Maybe a))
newStorage = do
q <- newChan
forkIO $ storage [] q
return q
newHandleStorage :: IO (Chan (String, Maybe (Chan [Handle]), Maybe Handle))
newHandleStorage = newStorage
storage :: (Eq a, Show a) => [a] -> Chan (String, Maybe (Chan [a]), Maybe a) -> IO()
storage s q = do
let loop = (`storage` q)
(req, reply, d) <- readChan q
print ("processing " ++ show(d))
case req of
"add" -> loop ((fromJust d) : s)
"remove" -> loop (delete (fromJust d) s)
"get" -> do
writeChan (fromJust reply) s
loop s
store s d = writeChan s ("add", Nothing, Just d)
unstore s d = writeChan s ("remove", Nothing, Just d)
request s = do
chan <- newChan
writeChan s ("get", Just chan, Nothing)
readChan chan
बिंदु यह है कि एक धागा (अभिनेता) वस्तुओं की एक सूची का प्रबंधन कर रहा है और आने वाले अनुरोधों के अनुसार सूची को संशोधित करता है। चूंकि धागा वास्तव में सस्ता है, मैंने सोचा कि यह वास्तव में एक अच्छा कार्यात्मक विकल्प हो सकता है।
बेशक यह सिर्फ एक प्रोटोटाइप (अवधारणा का त्वरित गंदा सबूत) है। तो मेरे सवाल है:
- इस (अभिनेता दुनिया में) साझा परिवर्तनशील चर के प्रबंधन के लिए एक "अच्छा" रास्ता नहीं है?
- क्या इस पैटर्न के लिए पहले से ही एक पुस्तकालय है? (मैं पहले से ही खोज की, लेकिन मैं कुछ भी नहीं मिला)
सादर, क्रिस
यदि आप अभिनेता मॉडल के विकल्पों का पता लगाने के इच्छुक हैं, तो मैं आपको हास्केल की [सॉफ्टवेयर लेनदेन संबंधी मेमोरी] (https://en.wikipedia.org/wiki/Software_transactional_memory) का प्रयास करने का सुझाव दूंगा। यह डेटाबेस लेनदेन के समान एक सुंदर तंत्र है। रियल वर्ल्ड हास्केल में [अध्याय 28] (http://book.realworldhaskell.org/read/software-transactional-memory.html) देखें। –
तकनीकी रूप से एक महान विकल्प है लेकिन मैंने सुना है कि बड़ी संख्या में थ्रेड (प्रति क्लाइंट एक थ्रेड जो हैकेल में मानक है) के साथ एसटीएम का उपयोग करना और अपेक्षाकृत लंबे परिचालन (सूची से किसी आइटम को हटाना ओ (एन) है, निश्चित रूप से हैश सेट/मानचित्र यहां मदद कर सकते हैं) बड़ी संख्या में एसटीएम के प्रदर्शन को कम कर सकते हैं। और निश्चित रूप से एमवीआर चैनल को एसटीएम चैनल द्वारा प्रतिस्थापित किया जा सकता है जिसका अर्थ है कि दो तकनीकों का सर्वोत्तम उपयोग करना। संपादित करें: इस तरह की स्थिति में अभिनेता पैटर्न आम तौर पर वास्तव में अच्छा होता है, क्योंकि किसी आइटम को हटाने/जोड़ने के लिए ओ (1) (केवल एक संदेश भेजना) वास्तविक काम धागे में किया जाता है ... – Kr0e
आप सही हैं। एसटीएम के साथ ऐसा हो सकता है कि कई बार लेन-देन फिर से शुरू हो जाते हैं, जिससे कम प्रदर्शन होता है। लेकिन यदि आपके सिंक्रनाइज़ किए गए ऑपरेशन लंबे समय तक लेते हैं, तो आप अभिनेताओं के साथ भी इसी तरह की समस्याएं प्राप्त कर सकते हैं - अगर इससे अधिक संदेश हैं, तो यह स्थिति वास्तविकता के पीछे रह जाएगी। तो संतुलित पेड़ ('मानचित्र'/'सेट') या' एसटी/आईओ 'आधारित हैश सेट का उपयोग निश्चित रूप से मदद करेगा। –