Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Killing a thread when MVar is garbage collected

I have a worker thread which reads data repeatedly from an MVar and performs some useful work on that. After a while, the rest of the program forgets about that worker thread, which means that it will wait on an empty MVar and become very lonely. My question is:

Will the MVar be garbage collected if threads no longer write to it, for instance because they all wait for it? Will garbage collection kill the waiting threads? If neither, can I somehow indicate to the compiler that the MVar should be garbage collected and the thread be killed?

EDIT: I should probably clarify the purpose of my question. I don't desire general protection against deadlocks; instead, what I would like to do is to tie the life of the worker thread to life of a value (as in: dead values are claimed by garbage collection). In other words, the worker thread is a resource that I would like to free not by hand, but when a certain value (the MVar or a derivative) is garbage collected.


Here an example program that demonstrates what I have in mind

import Control.Concurrent import Control.Concurrent.MVar  main = do     something     -- the thread forked in  something  can  be killed here     -- because the  MVar  used for communication is no longer in scope     etc  something = do     v <- newEmptyMVar     forkIO $ forever $ work =<< takeMVar v     putMVar v "Haskell"     putMVar v "42" 

In other words, I want the thread to be killed when I can no longer communicate with it, i.e. when the MVar used for communication is no longer in scope. How to do that?

like image 296
Heinrich Apfelmus Avatar asked Jun 03 '12 14:06

Heinrich Apfelmus


People also ask

Can a thread object be collected by the garbage collector while running?

No thread (or the things it refers to) will be garbage-collected while it is still running.

When GC run what happens to the thread?

run() will finish its execution, your current thread will sleep, and your while will continue its loop and do it over and over. The GC can hit at any point and, as others have stated, running threads (threads that were started with start() ) will only be GCed if they have finished their execution.

What is a thread Haskell?

Typically Haskell threads are an order of magnitude or two more efficient (in terms of both time and space) than operating system threads. The downside of having lightweight threads is that only one can run at a time, so if one thread blocks in a foreign call, for example, the other threads cannot continue.


1 Answers

It will just work: when the MVar is only reachable by the thread that is blocked on it, then the thread is sent the BlockedIndefinitelyOnMVar exception, which will normally cause it to die silently (the default exception handler for a thread ignores this exception).

BTW, for doing some cleanup when the thread dies, you'll want to use forkFinally (which I just added to Control.Concurrent).

like image 91
Simon Marlow Avatar answered Nov 07 '22 11:11

Simon Marlow