Link to home
Start Free TrialLog in
Avatar of KaranGupta
KaranGupta

asked on

Concurrency issues — Global Variables

Hi

Can some one explain with example and what is the solution to resolve this issue.


Regards
Karan
Avatar of m_walker
m_walker

Im not a c# coder, so I will leave the example (and points) to someone that is.
Are you talking about a multi treaded application accessing the same variable at the some time?

If so, I expect you will need to use a mutex to gain access to that variable.
As an approach....

wait for mutex "_mutex_var_1"
update variable
release mutex "_mutex_cat_1"

Hi Karan,

Can you please explain what is the problem you are facing with global variables?

Regards
Ankit
Hi,

As I understood by your question you can use
lock
{
}
On these variables when you are accessing them in multithreaded environment.
Avatar of KaranGupta

ASKER

Hi

I was reading an article why using global variable is a bad practice. This is one reason they stated as "Concurrency issues " in global variables. This is what I want to understand and what is the possible solution for this.


Regards
Karan Gupta
Sorry for the long post.  It will be as clear as mud so read and think and re-read.  Then ask questions.
Any code sample is only meant as an example and not actual code.  this post is about concepts.

Hope it helps in some way...

In a single theaded application, then you should not have concurrency issue, but you may use the same variable for two different things and end up with a little mess.

Consider this.
You have a global variable called Total1

Then in one function you set it up such that Total1 = 0
Then every time a "process_data" function gets called it sets Total1 += record_value;
So far so good.  Total1 is a global variable that has a running total of all records processed.
Now you call a sub_total procedure, in which you set Total1 = 0; while (some loop)  Total1+= LoopValue;
At which point Total1 now has a non-intended value.
In the sub_total procedure you call "process_data" and now Total1 is neither the Grand Total nor the SubTotal, a real mess.

As such the subtotal should be a local vairable so it cant be modified outside its function.

In a multi threaded application the mess can get bigger due to the same functions being called by different threads.  if the variables are local, then this will be thread safe, if not then the values will exists in every thread thus be changed by each thread.

If you need to have a global value in a multi threaded application (and there are some good reasons), you need to take care to ensure
1. The value is only used for the intended purpose.  This is done by you program design.
2. The value is not written two by two treads at the same time (this can result if application errors at worse, or invalid data at best).  This can be fixed by locking the variable as shown. by gkuhrd2001.

Think about this for a mulit threaded application.
You have an array for log lines.  You have a next_free pointer to the next free log entry, and a first_log entry to point to the first unprocessed log entry.
TSomeClass *LogLines[1000]; // 1000 Pointers to log data objects
int Next_Free = 0;
int First_Log = 0;

you now have a function called log data that can be called to add lines to the log list

void LogData (AnsiString LogData)
{
  LogLines[Next_Free] = new TSomeClass ();
  LogLines[Next_Free]->Time  = LogData.Time;
 LogLines[Next_Free]->LogData = LogData.LogData;
 Next_Free++;
}

Now two threads call LogData at the same time.
The first thread Creates a new object and stores it in Location 0 (next_free = 0)
The 2nd thread then runs for a while, creates a new (2nd) object and stores its point in location 0;
Then Next_Free++ in thread 2 (Next_Free = 1)
Then Next_Free++ in thread 1 (Next_Free = 2);

So we now have a valid object in location 0.  Its data will be how knows what. then we have an invalid pointer in Location 1 (as no valid object pointer was stored there)

So when the log_to_file function runs it will log some weird data from location 0 and delete that object to free up the memory.  Then application error on the invalid pointer in location 1.....  And the first object created is still taking up memory and you app cant use it.

As such a better code would be...

void LogData (AnsiString LogData)
{
 int LogPos;
   Some code to stop access to NextFree/or wait till NextFree is not locked.
   LogPos = Next_Free;
   Next_Free++;
  release lock on next_free;

  LogLines[LogPos] = new TSomeClass ();
  LogLines[LogPos]->Time  = LogData.Time;
 LogLines[LogPos]->LogData = LogData.LogData;
 
}
Hi m_walker

Thanks for working so hard on this post. I really appreciate that. But I need one favour from you. In the single threaded application you have taken one example in which you are setting the value of Total1 which is a global variable. If possible please give me some more logical example so that I can understand.

In the example given above I am not sure why should we set the value of Total1 in sub_total procedure.

Thanks in advance.

Regards
Karan Gupta
ASKER CERTIFIED SOLUTION
Avatar of m_walker
m_walker

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks