Threads example

Hey guys…
I’m studying threads on college (with c++) an someone told me that C# have thread system by default (C++ does not have it, you will need an extra lib to do that), and I had the necessity of learn how :smile:.

For those who don’t know what a thread is:
-Thread is a function that you can call paralleled with the main Unity’s thread. You can do, for an example, a infinity loop like “while(true){}” in a thread without crashing you app, because its being executed in another “process” than game’s one.

Well, thread is an advanced programming feature, and requires a bit of time to learn what it is, and what you can do with this…

For those looking for an “how to” for using threads on unity or even in another C# apps:

/*
 *This script just creats 2 threads that draw its number under a GUI label.
 * First time the button is used its call the start() of its respective thread.
 * Second time the button is used it pause/play the Thread.
 * To make it work, you just need to add this script to any object in the scene!
 * 
 * Made by Ivan S. Cavalheiro
 * Date: 10/05/2012
 * Mail: ivanscavalheiro@hotmail.com
 * Script vers.: 1.0
*/

using UnityEngine;
using System.Collections;
using System.Threading;

public class MainThreads : MonoBehaviour
{
	#region Public data
	public float timeWaiting = 5000000.0f;
	public string labelInitialText = "I`m the console here!";
	#endregion
	
	#region Private data
	private string _label;
	private Thread _t1;
	private Thread _t2;
	private bool _t1Paused = false;
	private bool _t2Paused = false;
	#endregion
	
	#region Start
	void Start () {
		_label = labelInitialText;
		_t1 = new Thread(_func1);
		_t2 = new Thread(_func2);
	}
	#endregion
	
	#region Threads
	private void _func1()
	{
		if(_label == labelInitialText)
			_label = "";
		while(true)
		{
			_label += 1;
			for(int i = 0; i < timeWaiting; i ++)
				while(_t1Paused){}
		}
	}
	
	private void _func2()
	{
		if(_label == labelInitialText)
			_label = "";
		while(true)
		{
			_label += 2;
			for(int i = 0; i < timeWaiting; i ++)
				while(_t2Paused){}
		}
	}
	#endregion
	
	#region OnGUI
	void OnGUI()
	{
		//--> Label that servers as a "console"
		GUI.Label(new Rect(0,0, 500, 500), _label);
		
		//--> Button for thread 1
		if(GUI.Button(new Rect(50, 50, 100, 50), "Thread T1"))
		{
			if(!_t1.IsAlive)
				_t1.Start();
			else
				_t1Paused = !_t1Paused;
			
		}
		
		//--> Button for thread 2
		if(GUI.Button(new Rect(50, 120, 100, 50), "Thread T2"))
		{
			if(!_t2.IsAlive)
				_t2.Start();
			else
				_t2Paused = !_t2Paused;
		}
	}
	#endregion
}
6 Likes

Muito obrigrado, Threading is a complicated subject, i heard that when you have to sync your threads is when the nightmares comes, please if you keep learning in this subject keep posting, when i studied we learned C without the ++ so i’m missing out a lot of fun and usefull stuff :slight_smile:

1 Like

I found this: " the Unity API isn’t thread-safe and can’t be used in threads."
and this:
“You can use your own threads for calculating something in the background or communicate with a native code plugin but not to interact with Unity.”

here: Threading in Unity - Questions & Answers - Unity Discussions

Maybe coroutines are the better way for doing parallel things if you access the unity api.

2 Likes

@rhasami
Yeah, i have no time to make more tests now, but i was able to change shared variables with threads…
this means that you can make classes with load functions and use this functions inside a thread, so your game wont have a kind of a freeze every time you want to load something…

of course you will need a good algorithm and a good programming logic to avoid errors like showing something that isnt loaded yet…

but again, this is a advanced programming feature.

@munei
i’ll. Syncing isn’t that hard! If you must wait some response from thread before making anything in the main thread just call the .wait() function, that will “stop” your program till that thread finish all it’s job

Its very good to have advanced professionals like you in the community.

Thank you very much

That code is not safe. You are not locking the variable _label !
Trust me, i just in the week passed a semester long labb series on operating system and process management where the labb was to implement process and file and thread managemnt to a school operting system in c, Pintos - Wikipedia .

Actually what you have posted is a classic example of when you get sync errors!
I will explain: Take the example that _label=10 and we are in _func1.
Now the line _label += 1; get translated to the psedo assembly code:

move.l _label to temporaryRegister1;
add.b 1 to temporaryRegister1;
move.l temporaryRegister1 to _label;

Lets say that we get an interrupt and a thread change directly after the add.l. (the example works after the first move.l also)
_func1 threads temporaryRegister1 will be 11 now. Now then _func2 gets to run, 5 times. And it will manage to bumb up _label to 15.
And we get interupt and thread switch back to _func1 thread. But thread1 temporaryRegister1 is still 11!!!
Thus when we reach “move.l temporaryRegister1 to _label;” _func1 will write 11 to _label when _label is 15!
Problem!
We need to lock, wither with lock or semaphore, the variable _label everytime we write or read it so that we do not get this error.

2 Likes

It will work fine as long as the two threads never run at the same time. :slight_smile:

Are you trolling me?

Just to clarify - Coroutines do not run in parallel.

1 Like

Can you explain why not? I thought they do.

Thanks

Coroutines are executed in the main thread where Update, FixedUpdate, and all other Unity’s stuff runs. So if you execute Thread.Sleep(10000) in a coroutine then the whole application will hang for 10 seconds.


Here is my version of the example. It doesn’t waste CPU time, terminates correctly, and, I hope, is thread safe (if not, please, let me know.)

using System.Threading;
using UnityEngine;

public class MainThreads : MonoBehaviour
{
	public string labelInitialText = "I'm the console here!";

	private string label;
	private volatile bool workInProgress = false;
	private Thread t1;
	private Thread t2;

	private volatile bool t1PausedFlag = false;
	private volatile bool t2PausedFlag = false;
	private volatile bool cancelFlag = false;

	private void Start()
	{
		label = labelInitialText;

		t1 = new Thread(Func1) {Name = "Thread 1"};
		t2 = new Thread(Func2) {Name = "Thread 2"};
	}

	private void Func1()
	{
		lock (label)
		{
			if (workInProgress == false)
			{
				workInProgress = true;
				label = "";
			}
		}

		while (cancelFlag == false)
		{
			lock (label)
			{
				label += "1";
			}

			do
			{
				Thread.Sleep(200);
			} while (t1PausedFlag);
		}

		Debug.Log(string.Format("{0} finished", Thread.CurrentThread.Name));
	}

	private void Func2()
	{
		lock (label)
		{
			if (workInProgress == false)
			{
				workInProgress = true;
				label = "";
			}
		}

		while (cancelFlag == false)
		{
			lock (label)
			{
				label += "2";
			}

			do
			{
				Thread.Sleep(200);
			} while (t2PausedFlag);
		}

		Debug.Log(string.Format("{0} finished", Thread.CurrentThread.Name));
	}

	private void OnGUI()
	{
		//--> Label that servers as a "console"
		GUI.Label(new Rect(0, 0, 500, 500), label);

		//--> Button for thread 1
		if (GUI.Button(new Rect(50, 50, 100, 50), "Thread T1"))
		{
			if (!t1.IsAlive)
			{
				t1.Start();
			}
			else
			{
				t1PausedFlag = !t1PausedFlag;
			}
		}

		//--> Button for thread 2
		if (GUI.Button(new Rect(50, 120, 100, 50), "Thread T2"))
		{
			if (!t2.IsAlive)
			{
				t2.Start();
			}
			else
			{
				t2PausedFlag = !t2PausedFlag;
			}
		}
	}

	private void OnApplicationQuit()
	{
		cancelFlag = true;
	}
}
2 Likes

This is a very good article to start with - http://www.albahari.com/threading/

A co-routine runs in a main thread, as alex said. A coroutine like

void Start() {
    StartCoroutine(ExampleCoroutine);
}
public IEnumerator ExampleCoroutine() {
    while(true) {
        yield return null;
    }
}

Would basically run every frame (similar to Update). The advantage is that you can spread calculations over several frames, for example moving the target to a certain position or do some expensive calculations (like AI, looking for close targets) over several frames so you don’t get short “lockups” (where the game freezes for 0.1 second)

1 Like

OK, here is the final solution for sync problems: mutex.

Mutex is a method that locks itself until it unlock itself. It can only be locked if its not already locked.
What i do in this new version of the script is lock a mutex before changing the label content, change label content and than unlock it.
If the another thread try to lock the mutex and its already locked, the thread will be forced to wait until its not locked anymore, so it can proceed.

/*
 *This script just creats 2 threads that draw its number under a GUI label.
 * First time the button is used its call the start() of its respective thread.
 * Second time the button is used it pause/play the Thread.
 * To make it work, you just need to add this script to any object in the scene!
 * 
 * Made by Ivan S. Cavalheiro
 * Date: 10/05/2012
 * Mail: ivanscavalheiro@hotmail.com
 * Script vers.: 1.2
*/

using UnityEngine;
using System.Collections;
using System.Threading;

public class Threads : MonoBehaviour
{
    #region Public data
    public float timeWaiting = 5000000.0f;
    public string labelInitialText = "I`m the console here!";
    #endregion   

    #region Private data
    private string _label;
    private Thread _t1;
    private Thread _t2;
    private bool _t1Paused = false;
    private bool _t2Paused = false;
	private Mutex _mutex = new Mutex();
    #endregion

    #region Start
    void Start () 
	{
        _label = labelInitialText;
        _t1 = new Thread(_func1);
        _t2 = new Thread(_func2);
	}
    #endregion

    #region Threads
    private void _func1()
    {
    	if(_label == labelInitialText)
            _label = "";
		
        while(true)
        {
           	_mutex.WaitOne();
				_label += 1;
			_mutex.ReleaseMutex();
			
            for(int i = 0; i < timeWaiting; i ++)
                while(_t1Paused){}
        }
    }

    private void _func2()
    {
       	if(_label == labelInitialText)
            _label = "";

        while(true)
        {
            _mutex.WaitOne();
				_label += 2;
			_mutex.ReleaseMutex();
			
            for(int i = 0; i < timeWaiting; i ++)
                while(_t2Paused){}
       	}
    }
    #endregion

    #region OnGUI
    void OnGUI()
    {
        //--> Label that servers as a "console"
        GUI.Label(new Rect(0,0, 500, 500), _label);

        //--> Button for thread 1
        if(GUI.Button(new Rect(50, 50, 100, 50), "Thread T1"))
        {
            if(!_t1.IsAlive)
                _t1.Start();
            else
                _t1Paused = !_t1Paused;
        } 

        //--> Button for thread 2
        if(GUI.Button(new Rect(50, 120, 100, 50), "Thread T2"))
        {
            if(!_t2.IsAlive)
                _t2.Start();
            else
                _t2Paused = !_t2Paused;
        }
    }
    #endregion
}
1 Like

Thanks Tseng, Alex for you explanation.

Still don’t understand 100%

If I do…

StartCoroutine("co1");
StartCoroutine("co2");
StartCoroutine("co3");

then all three Coroutines would run at the same time, not right? Still the same thread but kind of parallel? If this is not parallel what is this called? Semiparallel? Asynchron?

I know its not real multithreading, it always runs in the same thread, same core.

But if figured out for me its the best way to do things at the same time. Maybe not the fastest, then threads are better (just calculation, no unity api access), but only faster on multicore machines.

This is how I understand threads and coroutines. Please correct me if I am wrong.

Thanks a lot for explaining this.

A coroutine is actually nothing other than an IEnumerable implementation (in C# you must declare the return type as such)

    public IEnumerable ExampleCoroutine() {
    }

the “original” idea behind IEnumerable was to implement collections for the use in “foreach” statement. The IEnumerable interface has only 3 members: 1 “Current” Property and 2 Methods called “Reset” and “GetNext”. GetNext returns a boolean (true if there is a next object in the collection or false when there are no next objects)

A foreach loop would keep calling “GetNext” in each foreach cycle until it has iterated through the whole collection and then stop.

A good example of IEnumerator usage

using System;
using System.Collections.Generic;

public class Program
{
    static void Main()
    {
	//
	// Compute two with the exponent of 30.
	//
	foreach (int value in ComputePower(2, 30))
	{
	    Console.Write(value);
	    Console.Write(" ");
	}
	Console.WriteLine();
    }

    public static IEnumerable<int> ComputePower(int number, int exponent)
    {
	int exponentNum = 0;
	int numberResult = 1;
	//
	// Continue loop until the exponent count is reached.
	//
	while (exponentNum < exponent)
	{
	    //
	    // Multiply the result.
	    //
	    numberResult *= number;
	    exponentNum++;
	    //
	    // Return the result with yield.
	    //
	    yield return numberResult;
	}
    }
}

Source: C# yield Example - Dot Net Perls

Unity uses the IEnumerators in a similar way. Basically every code “inbetween” the yield statements is like an object in a collection (array, list, dictionary etc.) which is executed on each step (GetNext() call).

Also from the same site

Basically Unity keeps a list of all active IEnumerators (Coroutines) and on each update loops through this list, calling “GetNext” and removes it when it reaches the end. The “IEnumerator.Current” Property returns the current YieldInstruction (i.e. WaitForSeconds, WaitForFixedUpdate, WaitForEndOfFrame).

Something like this in pseudocode

foreach coroutine in coroutineList
    if coroutine.Current is null or coroutine.Current condition is true// i.e. time in seconds passed, end of frame reached etc. 
        if not coroutine.GetNext
            remove coroutine from coroutineList // GetNext returned false, the coroutine finished

Thanks a lot Tseng, that really helped and makes it much clearer.
StartCoroutine() just adds my function to the coroutine list which is handled by unity each frame.

Well it’s a very simplified explanation on it. It’s probably implemented slightly differently, only Unity developers know.

But that’s the basic idea on how it works

But its very good to understand the way you explained it.

Just one last question if this is ok.

I read somewhere (don’t remember where) its better use coroutines instead of the update function.
This would only make sense if I don’t execute the code in the coroutine each frame by using WaitForSeconds() or so. Just “yield return”
wouldn’t be a performance advantage.
Can you confirm this or is this a wrong conclusion?

Thanks again

Dunno, never did any performance tests on it.

Though I use Coroutines only when I have to, because if you call “StopAllCoroutines” it will stop any. So if you do some important stuff (like movement) in coroutines it will be stopped to, which may cause some unexpected behavior