- Home /
Unity 5 API multi thread safe?
Hi,
Recently I am digging into Threads , the thing I read that Unity APIs are not thread safe.
Though I also read Unity 5 has improved its multi threading jobs, so is that means Unity APIs can now be used in threading?
If not how to interact with Unity APIs with threading ?
Answer by YoungDeveloper · Apr 15, 2015 at 10:16 AM
There is nothing wrong in using threads. If you want them to communicate, simplest and quite effective way would be building event queueStack list with event objects - packets. If you want to process them as fast as update, then something like this will do.
//unity thread
private void Update(){
myThread.processQueue();
}
//my thread
//your thread which populates *queue* with events.
List<someData> queue = new List<someData>();
public void processQueue(){
for(int i = queue.Count-1; i >= 0; i--){
someData d = queue[i]; //do what you like
queue.RemoveAt(i);
}
}
Now this is Unity thread synchronized.
Wow,that is strong powerful stuff there,
Could you provide simple example with Action and events on how could this be done right way?
I am assu$$anonymous$$g that it will be something like storing List of Actions and then invoking it in Thread when event get called?
What happen if two events simultaneously get call? Two threads get created ?
Again thanks for info ,just little more spotlight will be much helpful
There is no standard method, you do it the way you need your system to function. I recently built such system for my custom mmo server, it would not be possible without multithreading and events. You should start with simple constants or enums to threat states and events.
@youngDeveloper Hi, I was implementing this solution, its working like a charm.
Though I have lil problem over one thing, how can I pause or stop threading from execution? Like for example user pause the game then threads should also get pause.
While researching I came to know about mutex and $$anonymous$$anualResetEvent functions, but not sure how to implement it ? Could you please elaborate on it?
$$anonymous$$y given example is not as clean as it looks like, if you test with tens, hundreds or millions you will most likely get an error, as generic list by default is not multiple thread safe. There are still some things to implement besides my example. What comes to thread pausing or sleeping then there are really hundreds of examples, even multiple stack overflow answer, i doubt i should be retelling what's already there.
Answer by fffMalzbier · Apr 15, 2015 at 10:13 AM
Unity 5 does use better threading for dividing his own jobs better like audio and and physic jobs on multiple threads.
The Unity API is still not thread save and can only be accessed from the main tread.
I see, Any Unity API which can be accessed? I read Vectors can be accessed, can collides be used too?
@idurvesh: All value types are automatically thread-safe since a single value can't be used by two or more thread at the same time since value types are always copied and never referenced. All classes derived from UnityEngine.Object are not thread safe. That includes almost all reference types that comes with Unity.
So all components (Transform, Collider, ...) can't be used in a thread either. What you can do, like YoungDeveloper roughly explained in his answer, is to copy some data into an array / list in the main thread, pass that array to a thread, let it process the data in some way and when finished read the data back from the main thread.
Be careful! "digging into Threads" might look easy at first glance as the abstract principle how a thread works is quite easy to understand. However when using threads what is most important is "knowing what you're doing" ^^. Threading introduces a huge variety of problems that can easily lead to random bug. In most cases you don't gain anything from using threads besides a lot of trouble :D
In general if you use thread to maximize the performance of some process, never use more threads than there are cores in your CPU. If you just want to use threads to seperate certain aspects you definitely use them wrong ^^. There are much safer and more predictable mechanisms out there for things like that (coroutines, finite state machines, strategy-pattern, ...).
It completely depends on what you actually want to do
"All value types are automatically thread-safe"... as I understand, that statement could be misleading, since non-atomic operations on value types (e.g., incrementing integers) can make it not-thread safe depending on which threads can read and which threads can update the variable's values.
I see, I do have Finite states machines n coroutines in it with lil bit dose of strategy pattern + behaviour trees, ....
Recently I come in contact with threads so was diggin into it....for performance,
Reading your comment put lot more spot light on my knowledge of threads with Unity....Thanks so much...
Just lil query as I asked to @younDeveloper
here is what I so far got,
void Start(){
start$$anonymous$$yThread();
}
List<Action> listToRunAtUpdate = new List<Action>();
void start$$anonymous$$yThread(){
ThreadPool.QueueUserWorkItem(x => myThreadFunction());
}
void myThreadFunction(){
/
/Thread code here
//at end
listToRunAtUpdate.Add(() => {
//UNITY CODE HERE
}});
}
void Update(){
if(listToRunAtUpdate.Count > 0){
listToRunAtUpdate[0]();
listToRunAtUpdate.RemoveAt(0);
}
}
I am stuck at pausing threadPool.....
could you plz point me towards right direction? Like how can I pause the thread and continue or abort with ThreadPool,
I know with Thread class I have option like start run stop abort....but what to do with ThreadPool?
@idurvesh: You should never ever consider stopping or pausing a thread from the outside. This will just lead to unpredictable results. The problem is that you simply don't know what the thread is currently doing. If a thread should be paused, you should implement that inside the thread at a convenient place. You can use any WaitHandles for that.
Further more what you do in your code is very dangerous as you don't do any syncronisation. You basically have two threads working possible at the same time with the same data. This can lead to literally everything (crash, data loss, access violations).
See this reworked implementation of the famous Loom class to actually schedule tasks in Update in a thread-safe way. (unfortunately Unity Gems itself is offline for quite some time now)
Also read those few points. Note: that are just a few things that might cause massive problems if not considered / handled carefully.
This also seems to be a quite well written resource on threads.
$$anonymous$$SDN shouldn't be missed. Their examples often are a bit stupid (sometimes even wrong), but all in all most the time a good source.
Eric Lipperts posts on SO are also always good reads. Btw: He worked at $$anonymous$$icrosoft and was in the $$anonymous$$m that created the C# compiler, so he really knows what's going on ^^.
The general rule is: If you can avoid it, don't use threads at all. In Unity there are even less cases where it would make sense to use threads. Also keep in $$anonymous$$d that Unity's classes aren't just not thread-safe but they actively forbid / prevent to use any method from another thread. They implemented a thread check in almost all methods of reference types which will throw an exception if called from another thread.
Wow, lot of resource, thanks so much @bunny83 , (Y)
and hey n just in case you missing UnityGems , then here is it ,saved on archive site..Each article written so far is available......
https://web.archive.org/web/20140208104956/http://unitygems.com/
Answer by QI · Aug 13, 2016 at 01:41 AM
The Unity's API is not thread safe, you have to execute them in main thread. Well you can try this package on Asset Store will help you to using threading easier. http://u3d.as/wQg You can simply use only one line of code to start a thread and execute Unity API safely.
Answer by aaimee712 · Sep 27, 2017 at 04:31 AM
Thank you for a great explanation. I was looking online for a similar idea and really appreciate it http://machinesembroidery.weebly.com
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Update Method doesn't see value set by other thread 0 Answers
Unity Threading Issue: Not able to delegate task 0 Answers
Google Daydream Thread with Unity 1 Answer