Click here to Skip to main content
15,885,767 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi,

I thought, it is simple to explain my problem with the pseudo code.

This is how my code looks like.

C#
public class A
{
 private object locker = new object();

    public bool pause = true;

//method created by first thread
private void M1()
{

while(true)
{
 // some lines of code

if(!pause)
CriticalMethod();

 }


}
//method created by second thread
private void M2()
{
while(true)
{
 // some lines of code
if(!pause)
CriticalMethod();
 }


}

//method created by third thread
private void M3()
{
while(true)
{
 // some lines of code
if(!pause)
CriticalMethod();
 }


}

//method created by fourth thread
private void M4()
{

while(true)
{
 // some lines of code
if(!pause)
CriticalMethod();
 }
}

       
        private void CriticalMethod()
        {

            lock (locker)
            {
pause=true;
                //doing critical task(critical section)
//pause=false;
            }
           
            
        }
}


Problem description:

There is a situation where 4 of my threads entered into "CriticalMethod" method.Using "lock", I can sync these threads but my requirement is not this.
My requirement is, when one of these threads first entered into this method, other threads even though entered into "CriticalMethod" method later(after some fraction of ms or ns) they should exit(i.e they should not execute critical section again and again after lock frees the shared object).Here "lock" written to handle some other things(which am not disclosing here).

Using "pause" variable, somehow I am able to make other threads skip entering "CriticalMethod" method but I know that it is not appropriate way.This trick works sometimes but not always.

So please share me the pseudo code how this situation can be handled.I referred many urls on this.Some of them suggested using of Semaphore,Monitor.TryEnter(object), Interlocked class.

Please suggest me which is efficient among them or any other way to do handle this.Simple, clean pseudo code helps me.Because in many urls it was difficult to me understand(especially Interlocked).I can understand "Semaphore", "Monitor.TryEnter(object)" but I do not think these will work in this case.

Assume that, pause variable value would be changed to "false" in some other parts of code(not disclosed here) and this happens once in a while.At that point of time, all threads entered into "CriticalMethod"(i.e. in fraction of ns or micro sec) and one thread entered into lock and others are stuck before lock.

Thanks and Regards,
Anil
Posted
Updated 28-May-15 5:12am
v2
Comments
Sergey Alexandrovich Kryukov 27-May-15 15:51pm    
Why?
—SA

1 solution

Tricky.

The issue is that, whatever check you make, setting a variable invariably happens later.

I have something similar but it's not guaranteed:

C#
List<something> _myList

List<something> MyList{
 get{
   if(_myList==null)
     lock(lockobject)
       if(_myList==null)
       {
         _myList = InitMyList();
         // do some other stuff
       }

  return MyList;
  }
}
</something></something>


I always assume that at least one thread will be stuck at the lock. I give the threads a chance to all threads coming in later to skip the lock. The thread that is stuck will eventually be allowed to enter the lock. Hence the second check. I want the second thread that was stuck at the lock to skip the init as well.

Does that help?
Andy ^_^
 
Share this answer
 
Comments
Anil Vittal 28-May-15 10:49am    
Thank you Andy.

These are few queries from me.

1) What is the importance of "MyList"?
2) Not able to determine global variables and method level variables!!
3) I request you to share improved pseudo code.

Actually, I am tired this time :-) That's why these questions.

Thanks and Regards,
Anil
Andy Lanng 28-May-15 10:58am    
Ok. I can see that there is some misunderstanding.

1) that is just an example
2) the variables are obvious. There is 1 private field, 1 private property and 1 object for the lock (not declared in the example)
3) don't say you're tired. I am too >_<

Take this:
A): You will never be able to guarantee that no thread will lock.
B): You can minimize the threat of thread lock
C): You need to perform a double-check around your lock:

bool _isBusy = false;

private void CriticalMethod()
{
if(!_isBusy)
'lock (locker)
'{
''if(!_isBusy)
''{
'''_isBusy = true;
'''//doing critical task(critical section)
'''_isBusy = false;
''}
'}
}
Anil Vittal 28-May-15 11:17am    
Sorry for troubling you :) I updated the question now.Changed initial value of "pause" variable to "true",last paragraph added,commented assigning pause to false in "CriticalMethod".
Andy Lanng 28-May-15 11:19am    
You will still get 1 or 2 locked threads but at least you have minimized the threat
Anil Vittal 4-Jun-15 10:11am    
Thanks Andy. From above solution, I got that, you provided another security for my code in "CriticalMethod" by keeping extra checking using "if" loop before "lock" statement. I do not find any importance of "if" loop within "lock" because _isBusy would be made "false" in previous thread(before executed thread). Did I miss something :)?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900