Hi everyoneI was considering starting to put some code in this blog, but was lacking the proper motivation. But I found one: trivia game!
So welcome to the first instalment of
Can You Spot the Deadlock?
Rules are simple: I publish some code which exhibits some concurrency related problem and ask some questions about it such as:
- What concurrency issue(s) is(are) present in the code? (deadlock, race condition, livelock…)
- Where does it occurs or what are the impacts?
- How can it be fixed
Please post your answer(s) in the comment section, I will provide the expected answers one week after first submission. Of course, debugging is not allowed here.
So without further ado, here is the first one, quite easy for a starter.
Where is the deadlock?
Which single line needs to be changed to fix this?
Problem is now closed, please see the solution.
class Program { /// Main function static void Main(string[] args) { DeadLock1 sample1 = new DeadLock1(); sample1.Start(); } } /// First instance of 'Can you Spot the DeadLock? /// Let's start easy to put things in motion internal class DeadLock1 { private Thread _firstRunner; private Thread _secondRunner; private bool _stopSignal = false; private readonly object _synchro = new object(); public DeadLock1() { _firstRunner = new Thread(FirstRunner); _secondRunner = new Thread(SecondRunner); } // start your engines public void Start() { _firstRunner.Start(); _secondRunner.Start(); Thread.Sleep(100); lock (_synchro) { _stopSignal = true; Monitor.Pulse(_synchro); } _firstRunner.Join(); _secondRunner.Join(); } // first thread logic private void FirstRunner() { lock (_synchro) { if (!_stopSignal) { Monitor.Wait(_synchro); } } } // second thread logic private void SecondRunner() { lock (_synchro) { if (!_stopSignal) { Monitor.Wait(_synchro); } } } }
Several quality comments can be made about this code, but please focus on the multithreading issues. Bonus points if the second design weakness is identified!
PS: I’ll wait a few days before approving comments not to disclose the solution. I already have at least one good answer (but not perfect) and one wrong one. Keep commenting!
edited to explicitly initialize _stopSignal for clarity.