Home > OS >  What to do about a global mutex locked from a thread that then is killed
What to do about a global mutex locked from a thread that then is killed

Time:10-27

As in the title. The functionality I need involves killing a running thread given some conditions. Unfortunately, if the said thread has locked a certain global mutex, that mutex will remain locked forever as I'm using a design where one thread tries to acquire the mutex, but it's only released after doing some work from another thread, which allows another call in the first thread to reacquire it again. Since the first thread is killed, the mutex is never unlocked and the second thread is stuck and unable to do anything about it.

I'd unlock the mutex after the thread is killed (that is, from a new instance of the same thread), but apparently that isn't permitted and results in undefined behaviour, because the mutex has to be unlocked from the same thread that has locked it. What can I do about this? Thanks.

CodePudding user response:

The functionality I need involves killing a running thread given some conditions.

Threads are an implementation detail. It is not possible to need to kill a thread for functionality unless there's a lot of code you can't control. If you are in that case, the fix is to isolate the thread you can't control into its own process. You can safely kill a process.

Otherwise, you cannot safely kill a thread. But you don't have to. What you need to do is stop the thread from doing the work you don't want it to do and make it do the work that you do want it to do.

You haven't described the work the thread is doing or the threading standard that you are using, so it's not easy to give you advice for the best way to do that. But generally there are two approaches:

  1. Have some shared state that tracks what work needs to be done. Have the code that does work that may need to be stopped check periodically if the work should be stopped.

  2. Use some kind of signaling method to signal the thread doing work that might need to be interrupted that the work it's doing may not need to be done anymore. This avoids the need for periodic checks but generally doesn't avoid the need for shared state.

As a last resort, just implement your own mutex that supports unlocking after thread death. That way, the thread will only hold an instance of this mutex which supports that functionality. In your implementation, there would be an internal boolean protected by an internal mutex that indicates that the mutex is held. That way, when the thread dies, you can just acquire the internal mutex, clear the internal boolean, and release the internal mutex.

Here's how your logic looks:

To lock the mutex:

  1. Acquire the internal mutex.
  2. While the internal boolean is true, wait on the internal condition variable.
  3. Set the internal boolean to true.
  4. Release the internal mutex.

To unlock the mutex:

  1. Acquire the internal mutex.
  2. Set the internal boolean to false.
  3. Broadcast the internal condition variable.
  4. Release the internal mutex.

Now, after thread death, you can just call the "unlock the mutex" operation above. (Make sure any state the mutex protects is consistent first, of course.)

CodePudding user response:

As @meaning-matters has suggested, this should be possible, at least on Linux, by intercepting the real-time signal 32 and using pthread_cancel, which is implemented using signals.

  • Related