.net - C# multithreading with Monitor hangs -
i reading msdn article, has examples managing threads monitor
class. running example on vs2012 in debug mode wasn't doing anything. assume threads blocking each other in kind of deadlock. can please explain, causing behaviour?
copying code post:
using system; using system.threading; using system.collections; namespace monitorcs1 { class monitorsample { const int max_loop_time = 1000; queue m_smplqueue; public monitorsample() { m_smplqueue = new queue(); } public void firstthread() { int counter = 0; lock(m_smplqueue) { while(counter < max_loop_time) { //wait, if queue busy. monitor.wait(m_smplqueue); //push 1 element. m_smplqueue.enqueue(counter); //release waiting thread. monitor.pulse(m_smplqueue); counter++; } } } public void secondthread() { lock(m_smplqueue) { //release waiting thread. monitor.pulse(m_smplqueue); //wait in loop, while queue busy. //exit on time-out when first thread stops. while(monitor.wait(m_smplqueue,1000)) { //pop first element. int counter = (int)m_smplqueue.dequeue(); //print first element. console.writeline(counter.tostring()); //release waiting thread. monitor.pulse(m_smplqueue); } } } //return number of queue elements. public int getqueuecount() { return m_smplqueue.count; } static void main(string[] args) { //create monitorsample object. monitorsample test = new monitorsample(); //create first thread. thread tfirst = new thread(new threadstart(test.firstthread)); //create second thread. thread tsecond = new thread(new threadstart(test.secondthread)); //start threads. tfirst.start(); tsecond.start(); //wait end of 2 threads tfirst.join(); tsecond.join(); //print number of queue elements. console.writeline("queue count = " + test.getqueuecount().tostring()); } } }
you using monitor.wait on same object have in lock. that's main problem. worth mentioning both lock , monitor.wait same thing under hood - double locking :). lock nice keyword compiler turns monitor.
coming high transaction background, best have private singleton object lock against. because reference in memory wont change - non static classes, possibly.
its worth mentioning having 2 threads start in right order have done in code may not result in them starting in right order.
here example of code written above suggestions (using lock keyword):
class locksample { const int max_loop_time = 50000; private static object queuelocker = new object(); queue m_smplqueue; public locksample() { m_smplqueue = new queue(); } public void firstthread() { console.writeline("in thread 1"); int counter = 0; lock (queuelocker) { console.writeline("adding queue"); while (counter < max_loop_time) { //push 1 element. m_smplqueue.enqueue(++counter); } } } public void secondthread() { console.writeline("in thread 2"); lock (queuelocker) { console.writeline("removing items queue"); while (m_smplqueue.count > 0) { //pop first element. int counter = (int)m_smplqueue.dequeue(); //print first element. console.write("\r{0}", counter.tostring()); } } } static void main(string[] args) { //create monitorsample object. locksample test = new locksample(); //create first thread. thread tfirst = new thread(new threadstart(test.firstthread)); //create second thread. thread tsecond = new thread(new threadstart(test.secondthread)); //start threads. tfirst.start(); thread.sleep(100); tsecond.start(); //wait end of 2 threads console.writeline("waiting thread 1"); tfirst.join(); console.writeline("waiting thread 2"); tsecond.join(); console.writeline("\r\nfinished!"); console.read(); } }
Comments
Post a Comment