views:

404

answers:

5

Ok.. here is some background on the issue. I have some 'critical' code that i'm trying to protect with a mutex. It goes something like this

Mutex.Lock()

// critical code // some file IO

Mutex.Unlock().

Now the issue is that my program seems to be 'stuck' due to this. Let me explain with an example.

Thread_1 comes in; and go to Mutex.Lock() and starts executing the critical code. In the critical code; it needs to do some File IO. Now at this point; I believe a 'context switch' happens and Thread_2 comes in and blocks on the Mutex.Lock() (since Thread_1 has the lock). All seems fine but in my case; the program 'hangs' here.. The only thing I can think of is that somehow Thread_2 keeps blocking for ever and doesn't switch back to Thread_1??

More info: using pthread_mutex_init and pthread_mutex_lock on linux.

+1  A: 

This sounds like a deadlock where Thread_1 is in the mutext and waiting on Thread_2 to release something, while Thread_2 is waiting to enter the mutex and so can't release whatever it is that Thread_1 needs.

edit: swapped thread names to more closely match the scenario in the question, added 'in the mutex'

John Knoeller
It does sound like deadlock. But I would re-word your answer a bit.
Martin York
@Martin: I'm open to suggestions.
John Knoeller
AFAIK; Thread_1 is already past the 'Mutex.Lock()' and is about to do some File IO. At this point Thread_2 comes in and 'hangs' on the Mutex.Lock().
shergill
Why not attach a debugger and find out where it's stuck?
James McNellis
Is that file IO a blocking read by any chance? From a pipe/socket?
Nikolai N Fetissov
As Nikolai says, that IO does sound like the key. Shergill can you tell us what kind of object you are doing IO From? Maybe some code?
John Knoeller
+2  A: 

The best solution for something like this is to use the debugger (gdb?). It is better if you use any IDE with debugger (eclipse?) to make debugging easier and more visual.

Like this you will see the location at which every thread is waiting.

What I expect is that Thread1 locks the mutex to enter the critical section, the stuck in the IO (may be wrong reading or infinite loop) and thread two is normally waiting for Mutex to be unlocked.

It doesn't seem that this is a dead lock, because dead lock can't happen with a single mutex!

Yousf
A: 

The context switch is irrelevant so long as there's just one lock. The other thread can't do anything to affect the first one as it will just be waiting on the lock until it gets it. So the problem is with the first thread somehow. Debuggers are pretty much worthless for multithreading but deadlocks are usually easy to resolve, as someone pointed out probably the first thread is in an infinite loop somehow.

Charles Eli Cheese
+5  A: 

As others have mentioned, you probably have a deadlock.

Sidenote:

You'll want to make sure that there aren't any uncaught exceptions thrown in the critical block of code. Otherwise the lock will never be released. You can use an RAII lock to overcome this issue:

class SingleLock {
public:
  SingleLock(Mutex &m) : m(m) { m.Lock(); }
  ~SingleLock() { m.Unlock(); }
private:
  Mutex m;
};

...
{ 
  SingleLock lock(mutex);
  // critical code // some file IO

}
...
Mr Fooz
A: 

Does the File I/O need to be part of the critical section? If Thread 1 is doing a blocking read, and Thread 2 is what is supposed to be writing to that file (or pipe or similar), then Thread 1 will never return to release the mutex. You should evaluate your critical sections to determine what actually needs to be protected by the mutex. It's considered good practice to have your critical sections be as small as possible.

mbyrne215