Main Site Documentation

Synchronizing Threads


#1

Hi guys, I need an advice from you.I’m trying to build an application composed by 2 parts: Main and IOEvents.
Just to give an idea of the think I want to do, this should works as a state machine, that is the Main part is a switch/cases statement that set different flags and parameters of my machine depending on which case it is, while IOEvents part checks every X seconds the situation of I/O, buses and other signals generated by external devices (temperature sensors, buttons, IR beams, etc).

Both these parts share the same class GClass that contain all the variables needed to run the machine. Furthermore these parts are two different threads.
Ok, here is the question: how can I sinchronize these threads in order to access correctly the shared variables class ??
Use LOCK statement for every variable acess is too complicated…
Any hints ?

Thanks in advance
Paolo


#2

You can wrap each variable into a property and do locks in get/set methods.
Other than that a piece of you code will help us to get a better idea on how to help you.


#3

Ok.Below an example of my application code.



    public class Program
    {
        

        public static void Main()
        {

            Global.TH_Main = Thread.CurrentThread;
            Global.TH_IOEvents = new Thread(new ThreadStart(IOEvents));
	  
	  private static void MainCycle()
		{
            Global.currentDisplayPage = 1;
            
            while (Global.RUN_APPLICATION)
            {
            
                switch (Global.currentDisplayPage)
                {
				case 1:
					loadPage1();
					break;
				case 2:
					loadPage2();
					break;
				case 3:
					loadPage3();
					break;
				case 4:
					loadPage4();
					break;
					
					...
					
				}
				
			}
			
			
			
			private void  loadPage1()
			{
				if(TSensorON == true)
				{ temperatureSens1 = checkTemperature();}
				
				dataToDisplay = DataContainer[x];
				
				if(MotorIsRunning)
				{ 
					tableValue = 0xFF;
					switchOnLedGreen = true;
				}
				else
				{ 
					tableValue = 0x0F;
					switchOnLedGreen = false;
				}

				//and so on with other R/W accesses to shared class variables
				...
			
			}
			
			private void  loadPage2()
			{
				//Similar to loadPage1
				...
			
			}
			
			private void  loadPage3()
			{
				//Similar to loadPage1
				...
			
			}
			
			private void  loadPage4()
			{
				//Similar to loadPage1
				...
			
			}


Here is the variables shared class :



    static class  Global
    {
   
           public static bool RUN_APPLICATION ;
	
			public static int currentPage;
	
			public static byte tableValue;
			public static  bool switchOnLedGreen;
			
			public static  bool MotorIsRunningFlag;
			
			public static SensorSignal TSensorON;
			
	}
	


Here is the IOEvents function that is performed by the 2° Thread:



      private static void IOEvents()
      {
		if(MotorIsRunning)
		{ 
			//Check the speed
			if(MotorSpeed == HIGH)
			{
				switchOnLedGreen = true;
				sleep(500);	
				switchOnLedGreen = false;
			}
				
			DataContainer[x+100] = 0xA2;
			
			//and so on with other R/W accesses to shared variables
			...
	}
	


This is a NONSENSE example. It’s just to show you the structure of my application. I hope it’s clear enough! Any advices will be welcome :slight_smile: !

Thanks in advance
Paolo


#4

The best way to achieve thread safety for what you’re trying to do is to use the lock keyword, like Architect mentioned. Your example code has this:


static class Global
{
	// ...

	public static bool switchOnLedGreen;

	// ...
}

One way to ensure thread safety for Global.switchOnLedGreen (for example) would be to change your Global class to something like this instead:


static class Global
{
	private static object greenLedLock = new object();
	private static bool switchOnLedGreen = false;

	public static bool SwitchOnLedGreen
	{
		get
		{
			lock (Global.greenLedLock)
			{
				return Global.switchOnLedGreen;
			}
		}

		set
		{
			lock (Global.greenLedLock)
			{
				Global.switchOnLedGreen = value;
			}
		}
	}

	public static void CycleGreenLed()
	{
		lock (Global.greenLedLock)
		{
			Global.switchOnLedGreen = true;
			sleep(500);	
			Global.switchOnLedGreen = false;
		}
	}

}

So you would change all references to Global.switchOnLedGreen to Global.SwitchOnLedGreen, and you could change this (which I’m assuming is a critical section):


//Check the speed
if(MotorSpeed == HIGH)
{
	switchOnLedGreen = true;
	sleep(500);	
	switchOnLedGreen = false;
}

To this:


//Check the speed
if(MotorSpeed == HIGH)
{
	Global.CycleGreenLed();
}

This is just an example…hopefully it makes sense? I’m probably not 100% clear on what you’re trying to accomplish in your code, but maybe you get the idea. Using lock() really is the easiest and safest way to accomplish basic synchronization in the .NET world, even if it can be tedious.


#5

Thanks for the answer. I agree with you, the lock seems to be the simplest solution, but perhaps i think i should revise something in my code.
Anyway what do you think about the memory consumption changing the declaration of a simple variable to a creation of a property for the variable? It’s heavy? Consider that i should do it for more or less 30 variables… ???:frowning:

Thanks again
Paolo


#6

I don’t think [italic]memory[/italic] consumption will be a huge problem, but there is always a slight performance hit when using get/set properties vs. accessing variables directly, because the compiler converts all getters/setters to actual method calls behind the scenes. However, I wouldn’t worry too much about that right now. First, I would concentrate on getting your code functional, using properties and lock statements (or whatever makes the most sense) to make sure your member fields are synchronized properly. You might not even need a lock() statement for every single member, it just depends on what you’re trying to accomplish. After you get everything working, then and only then would I worry about performance issues. You’ll probably find out that your code performs fine as-is.