Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ C++/CLI C#
I have some code in a C++ CLR program with the below Critical Section code.
<pre lang="xml">
///Test.cpp
static CRITICAL_SECTION	PrintCriticalSection;
void Test(int sleep1,int threadNumber)
    {
        cout&lt;&lt;&quot;Thread &quot;&lt;&lt;threadNumber&lt;&lt;&quot; Starts. Sleeping for &quot;&lt;&lt;sleep1&lt;&lt;&quot; seconds.\n&quot;;
        EnterCriticalSection(&amp;PrintCriticalSection);
        Sleep(sleep1);
        LeaveCriticalSection(&amp;PrintCriticalSection);
        cout&lt;&lt;&quot;Thread &quot;&lt;&lt;threadNumber&lt;&lt;&quot; Ends.\n&quot;;
 
    }</pre>
 
I am calling this code using 2 Threads
<pre lang="xml">
class Program
    {
         Thread thread1;
         Thread thread2;
         PhoneCLR.PhonePortCLR test1;
         PhoneCLR.PhonePortCLR test2;
        static void Main(string[] args)
        {
            Program program1=new Program();
            program1.Test1();
             }
 
        void Test1()
        {
            test1 = new PhonePortCLR(1, 1, 1, 1, true, false, true, false, 1);
            test2 = new PhonePortCLR(1, 1, 1, 1, true, false, true, false, 1);
            PhonePortCLR.InitGlobalOnce(1, false, false, false, false);
            thread1 = new Thread(new ThreadStart(function1));
            thread2 = new Thread(new ThreadStart(function2));
            thread1.Start();
            thread2.Start();
           
            Console.ReadLine();
        }
       
         void function1()
        {
            test1.Test(10000, 1);
        }
         void function2()
        {
            test2.Test(100,2);
        }
    }
}
</pre>
 
The output in console window is supposed to be :
 
Thread 2 Starts. Sleeping for 100 seconds.
Thread 1 Starts. Sleeping for 10000 seconds.
///There is supposed to be a pause of 10,000 seconds here
Thread 2 Ends.
Thread 1 Ends.
 
But the output I am getting is random. Sometimes I get the above but sometimes I get below Output. It is so weird. Why is this the case? What can I use instead to fix this issue? Help!!!!! Its like 1 in 6 times I get below output. I am glad I caught this. I also notice that if I make the variable global instead of static, I get the below every time( Critical Section does not work)
 
The output in console window is sometimes:
 
Thread 2 Starts. Sleeping for 100 seconds.
Thread 1 Starts. Sleeping for 10000 seconds.
Thread 2 Ends.
///The 10 second pause happens now here...
Thread 1 Ends.
Posted 22-Jan-13 17:44pm
Edited 22-Jan-13 17:50pm
v2
Comments
Sergey Alexandrovich Kryukov at 23-Jan-13 0:09am
   
Please let me inform you that you've committed a serious abuse. Each and every of your "answers" in this forum is an abuse of different degree. All such "answers" are fake. Most of them are other questions. Worse, some of them you accepted by yourself, which can be qualified as cheating.
 
Is there anything you are going to do with that?
—SA
jobin007007 at 23-Jan-13 0:44am
   
I am not sure what you mean . You are talking about this thread?
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

This is exactly the expected result.
 
You misuse CriticalSection in such a funny way which I never even imagined. What do you "protect" with it? The call to Sleep!
 
Case closed.
 
I cannot imagine the way you could possibly think. Unless this is a slip of a hand, I would say you have no idea what CriticalSection is used for. Try to understand it. For this purpose, read this: http://en.wikipedia.org/wiki/Mutual_exclusion[^].
 
Better now? Smile | :)
 
—SA
  Permalink  
v3
Comments
jobin007007 at 23-Jan-13 0:01am
   
This is merely test code i wrote to prove that Thread 2 is able to get past Thread1. I want Thread 2 to not execute when it is entering Critical sections. I guess you have to follow the examples a little bit more. Does that make it more clear?
Sergey Alexandrovich Kryukov at 23-Jan-13 0:05am
   
Please tell me: do you sandwich Speep with critical section calls or not? I can see it right now.
—SA
jobin007007 at 23-Jan-13 0:09am
   
Yes I put a sleep there depending on the thread. The sleep is there to identify that Thread 2 is not able to get past the sleep time of Thread 1 and gives me visual confirmation.
Sergey Alexandrovich Kryukov at 23-Jan-13 0:13am
   
OK, that settles the case. I understand the possible purpose of sleep, but your critical section does nothing. Look, I'm too lazy to describe the scenario showing the output you got. You can do it by yourself. In other words, you don't do any synchronization, substitute it with so called "race condition" (read about it) instead.
—SA
jobin007007 at 23-Jan-13 0:21am
   
I think I found out why...See my comments. Is that what you mean?
Yes the sleep does nothing other than let me count that 10 seconds have elapsed and thread 2 is not outputting anything on the screen.
Kuthuparakkal at 23-Jan-13 0:05am
   
good answer 5+
Sergey Alexandrovich Kryukov at 23-Jan-13 0:07am
   
Thank you very much.
 
Please take a look at my comment to the question, above.
—SA
jobin007007 at 23-Jan-13 0:18am
   
I might have found out the reason why I have the problem. When I start the 2 threads, there is no guarantee that Thread1 or Thread 2 will be starting first. I put the below to make sure that thread2 will always be starting first and this seemed to make sure that Thread 2 will not access the function Test critical section region if Thread2 is already there.
thread1.Start();
Thread.Sleep(1000);
thread2.Start();
Sergey Alexandrovich Kryukov at 23-Jan-13 0:21am
   
Wrong. You are not using CriticalSection properly.
 
Here is the experiment to do: Move Enter to the very beginning of the Test method, Leave — to the very end. All your cases of "entangled" calls will disappear immediately, I'll guarantee that.
 
Got the hint?
 
—SA
Sergey Alexandrovich Kryukov at 23-Jan-13 0:23am
   
And let me warn you: all your thinking is in the ways of "race condition", which produce stochastic behavior. Isn't it obvious? Unpredictable order of execution.
jobin007007 at 23-Jan-13 0:24am
   
I think you might have to run the sample to understand. I might have made the example hard to follow.
Isn't the output correct if critical section is working?
 
Thread 2 Starts. Sleeping for 100 seconds.
Thread 1 Starts. Sleeping for 10000 seconds.
///There is supposed to be a pause of 10,000 seconds here
Thread 2 Ends.
Thread 1 Ends.
Sergey Alexandrovich Kryukov at 23-Jan-13 0:26am
   
Who has problems, you or me? Did you do what I advised? No.
It's useless to help anyone who cannot listen.
You should do the experiment I just described above, only then we can continue discussion, OK?
—SA
jobin007007 at 23-Jan-13 0:29am
   
Ok wow. You are right . that was an easier example to implement. I don't know why my test case was like that.
jobin007007 at 23-Jan-13 0:30am
   
Thanks for answering.
Sergey Alexandrovich Kryukov at 23-Jan-13 0:40am
   
I told you that I would guarantee that. :-)
 
OK, now you probably can get it.
Please, read the referenced article and just think a bit at this sample, I'm sure you will derive correct conclusion.
 
I think now you can accept the answer formally (green button), right?
 
—SA
jobin007007 at 23-Jan-13 0:26am
   
Sorry as below after i put the sleep.
 
Thread 1 Starts. Sleeping for 10000 seconds.
Thread 2 Starts. Sleeping for 100 seconds.
///There is supposed to be a pause of 10,000 seconds here
Thread 2 Ends.
Thread 1 Ends
Sergey Alexandrovich Kryukov at 25-Jan-13 14:41pm
   
Oh, I can see you did not accept this answer but instead added your own and, again, self-accepted it. Don't you think it's called cheating?
—SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

Fixed by moving critical section to top of the test code
and adding
thread1.Start();
Thread.Sleep(1000);
thread2.Start();
 
static CRITICAL_SECTION	PrintCriticalSection;
void Test(int sleep1,int threadNumber)
    {
         EnterCriticalSection(&PrintCriticalSection);
        cout<<"Thread "<<threadNumber<<" Starts. Sleeping for "<<sleep1<<" seconds.\n";
       
        Sleep(sleep1);
        
        cout<<"Thread "<<threadNumber<<" Ends.\n";
        LeaveCriticalSection(&PrintCriticalSection);
    }
 
 

class Program
    {
         Thread thread1;
         Thread thread2;
         PhoneCLR.PhonePortCLR test1;
         PhoneCLR.PhonePortCLR test2;
        static void Main(string[] args)
        {
            Program program1=new Program();
            program1.Test1();
             }
 
        void Test1()
        {
            test1 = new PhonePortCLR(1, 1, 1, 1, true, false, true, false, 1);
            test2 = new PhonePortCLR(1, 1, 1, 1, true, false, true, false, 1);
            PhonePortCLR.InitGlobalOnce(1, false, false, false, false);
            thread1 = new Thread(new ThreadStart(function1));
            thread2 = new Thread(new ThreadStart(function2));
            thread1.Start();
            Thread.Sleep(1000);
            thread2.Start();
           
            Console.ReadLine();
        }
       
         void function1()
        {
            test1.Test(10000, 1);
        }
         void function2()
        {
            test2.Test(100,2);
        }
    }
}
  Permalink  

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

  Print Answers RSS
0 Sergey Alexandrovich Kryukov 480
1 Gihan Liyanage 225
2 OriginalGriff 174
3 Bhavik_Patel 170
4 PhilLenoir 155
0 Sergey Alexandrovich Kryukov 8,653
1 OriginalGriff 7,132
2 CPallini 2,598
3 Richard MacCutchan 2,060
4 Abhinav S 1,808


Advertise | Privacy | Mobile
Web01 | 2.8.140827.1 | Last Updated 23 Jan 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100