当我用Java打印某件东西时,我通常会将线程的名称附加到print语句中,这样我就知道哪个线程正在运行什么print语句。如何在Haskell中获取和设置线程名?如果不能设置线程名,如何使线程具有给定的名称?
注意:我通常给线程以描述性的名称,如"GUI_thread“、"main_thread”、"database_thread“等等。
发布于 2016-02-09 21:37:50
正如我在评论中所说的,您可以使用labelThread
给线程一个标签。遗憾的是,我找不到办法把这个标签拉回来(我只找到了这个无效票,有人想要这样做)。
但是,正如在Haskell中的并行并行编程中描述的那样,您可以在以下方面获得事件日志视图:
(从那以后--希望没人介意):
main = do
t <- myThreadId
labelThread t "main"
m <- newEmptyMVar
t <- forkIO $ putMVar m 'a'
labelThread t "a"
t <- forkIO $ putMVar m 'b'
labelThread t "b"
traceEventIO "before takeMVar"
takeMVar m
takeMVar m
然后,您应该使用threaded
和eventlog
开关集编译它:
ghc mvar4.hs -threaded -eventlog
并且可以用+RTS
和-l
调用它。
./mvar4 +RTS -l
最后,您可以使用ghc-evetns
查看输出
ghc-events show mvar4.eventlog
天真的自我实现
这似乎不是您想要的,所以这里有一个(非常基本的)例子,说明您如何能够自己做到这一点(只使用列表和MVar
来保持ThreadId
与其名称之间的关联):
import Control.Concurrent
type Labels = MVar [(ThreadId, String)]
initLabels :: IO Labels
initLabels = newMVar []
labelThread :: Labels -> ThreadId -> String -> IO ()
labelThread labels threadId label =
modifyMVar_ labels (\assocs -> return $ (threadId, label):assocs)
getLabel :: Labels -> ThreadId -> IO String
getLabel labels threadId = withMVar labels (\assocs ->
case lookup threadId assocs of
Just label -> return label
Nothing -> return $ show threadId)
你可以这样用它:
main :: IO ()
main = do
ls <- initLabels
myId <- myThreadId
getLabel ls myId >>= print
labelThread ls myId "my Thread"
getLabel ls myId >>= print
这会让你:
λ> :main
"ThreadId 50"
"my Thread"
显然,如果创建大量线程,这可能不是一个好主意。至少,您应该添加一些东西,以便在线程的末尾再次删除标签:
removeLabel :: Labels -> ThreadId -> IO ()
removeLabel labels threadId =
modifyMVar_ labels (return . filter ((/= threadId) . fst))
forkLabeledIO :: Labels -> String -> IO () -> IO ThreadId
forkLabeledIO labels label computation = forkIO $ do
myId <- myThreadId
labelThread labels myId label
computation
removeLabel labels myId
..。是的,我知道:讨厌--当然,Map
也是一个更好的主意--但我希望你能得到基本的想法。
https://stackoverflow.com/questions/35278498
复制