
For the attached programme, in the task-getting,
else if Set.null work then return Nothing else retry
doesn't really make sense, when the channel is empty, we could return Nothing right away. I suppose, in the real programme, some threads might write further tasks to the channel, so while not all threads have finished, the channel might not be permanently empty? Correct. This is a simplified and reduced to the basics example of a taskpool where threads can write tasks back. Hence, we have to check
Hello, that no other threads are working before we return a "we are really finished"-Nothing message.
end all threads and prevent hanging. If yes, writing strict values to working:
get chan working = do tid <- myThreadId
-- atomically commit that this thread is not working anymore (since we -- try to get a task we must be quasi-idle! atomically $ do work <- Set.delete tid `fmap` readTVar working writeTVar working $! work
-- waits for a new task. if all threads are idle and the pool is empty, -- return. atomically $ do empty <- isEmptyTChan chan work <- readTVar working
if (not empty) then do task <- readTChan chan writeTVar working $! (Set.insert tid work) return (Just task) else if Set.null work then return Nothing else retry
seems to prevent hanging on my box (running fine with "100 64 1 +RTS -N" nearing task 60000, without the strict writes it typically hangs after a few dozen or hundred runs). Nice idea, didn't try the strict write. Even though I have no explanation why lazy evaluation causes so much trouble...
I'd ask such things on glasgow-haskell-users, less traffic, it's a GHC- specific list, you're more likely that one of the GHC experts notices it there and can tell you whether it's a bug, a feature or an error in your code. Good idea, totally forgot it. Will do next time (or, if noone has an explanation of this behaviour), repost my message there.
But hopefully someone of the GHC experts read this too, so we won't duplicate knowledge :-) Cheers, Michael