• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2572
  • Last Modified:

Critical Section implementation in C

Hello sharks!

I'm trying to implement the following code in C (not C++) with threads and CS.
For some reason, it seems it does not affect the threads and they all enter the CS.
The app is Win32 based using MS-Visual.
I know this implementation might cause starvation, but i don't care at the moment.. ;)

Please help..



// the paseudo code:

static int cs = 0;

void main()
{
   // run some threads...
}

void thread()
{
   if (cs == 1)
      while(cs);
   cs = 1;

   // do CS here..

   cs = 0;
}
0
ben-gur
Asked:
ben-gur
  • 3
  • 3
  • 2
  • +1
1 Solution
 
codez80Commented:
well first things first. what u r doing is called spinning which basically eats cpu!

add a Sleep(0) statement to give time to other threads to solve that.

second change your decl of int cs to "static volatile int" to avoid optimisation you do not want to help with synchronisation.

good luck

codez80
0
 
grg99Commented:
Well, you're theoretically fubarred... You could get a thread switch between the test "cs==1" and the set "cs = 1";
It won't happen often, but it WILL happen.

You could do somewhat better with something paranoid like:

cs++;
while( cs > 1 ) {  sleep( 0 ); /* two of us got the lock!! */ }

... do the critical stuff...

cs--;





But that STILL has a small hole- you could BOTH get the lock, then both spin waiting for the other guy to finish..  


to do it the RIGHT way:

You need an atomic test-and-set operation, something which can't be guaranteed in "pure" C.

Try using some of the Windows API for semaphores..  I don't remember what it's called, but it exists.  IIRC on Windows/98 it is a very efficient 2-instruction routine.




0
 
mrwad99Commented:
It may help your thinking when it comes to critical sectionsto look at this small piece of code.

Basically this program has one thread updating values in a global array and the main thread outputting the contents of the array.  

If the main thread interrupts the worker thread before it has finished updating *all* of the elements in the array, then the main thread will output values that are not all the same (obviously).  

However the use of the CS ensures that the worker thread finishes updating all of the elements in the array *before* the main thread can output them.

This can be adopted for your purposes with multiple threads easily enough.

If you need more flexibility than given here you may need to consider semaphores as mentioned earlier.

#include <windows.h>
#include <process.h>
#include <stdio.h>

CRITICAL_SECTION cs;

int a[5];

void Thread(void* pParams)
{
     int i, num = 0;
     
    while (1) {
          EnterCriticalSection( &cs );
          printf("In the thread process, num is %i\n", num);
          for (i = 0; i < 5; i++) {
               a[i] = num;
          }
          num++;
          LeaveCriticalSection( &cs );
         
    }
}

int main(void)
{
     InitializeCriticalSection( &cs );

     _beginthread(Thread, 0, NULL);
     while(1) {
          EnterCriticalSection( &cs );
          printf("In the main process\n");
        printf("%d %d %d %d %d\n",  a[0], a[1], a[2], a[3], a[4] );
        LeaveCriticalSection( &cs );
     }
     return 0;
}
 
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
ben-gurAuthor Commented:
Thank you all for your replies. It was very helpful.

Adam Ben-Gur.
0
 
ben-gurAuthor Commented:
Thanks man!
0
 
mrwad99Commented:
Glad to help !
0
 
codez80Commented:
I THOUGHT YOU WERE GOING TO IMPLEMENT CRITICAL SECTION YOURSELF RATHER THAN RELYING ON WIN32 APIs!!!

codez80
0
 
ben-gurAuthor Commented:
Hey codez80,

No need to shout..
I tried to implement it myself because i was unable to use the build-in methods due to C++/C conventions (and also I was probably implementing it wrong..).
I also tried your solution but it seems it didn't work - the threads were still accessing CS at the same time.. (Still don't know why).

Anyhow, the example mrwad99 posted solved the problem, and now it seems everything is running smoothly.

I'm sorry you didn't got the points, but I can choose only one.. Thanks for your time and help man.

Adam.
0
 
mrwad99Commented:
As a further note ben-gur it is generally better to use
_beginthreadex as opposed to _beginthread for a mulitude of reasons.

The example I posted here is adequate for _beginthread use as there is no explicit closing of the thread which is where the problem with _beginthread lies.

You can find out more about this function by using google or another popular search engine.

:D
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 3
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now