Skip to main content
gamedev.net
🔒 Locked 🎮 Unity

Thread-safety

Started by arthur83 Mar 30, 2007 at 12:46 PM 2 replies 700+ views
Original Post
arthur83
arthur83
I'm getting a headache working with multiple threads. To achieve thread-safety when using a shared resource between threads, is a function still thread-safe even if it calls other functions that are thread-safe? I imagine a scenario like this (I'm working in C++...): An object has a function Restart() that calls Stop() and Start() in sequence. If both Start() and Stop() are thread-safe, as the their bodies are critical sections, is Restart() also thread-safe? What if another function calls Start() in the middle of Restart()? If Restart() is not thread-safe, how can I achieve it?
Antheus
Antheus
If restart is atomic in the sense that it doesn't touch any other resources, then yes, it's thread-safe.

But, the question to be answered here is, what is the state of the resource between start() and stop(). Must a sequence of these two operations when called through restart() be atomic, or can start() and stop() happen arbitrarily apart.

What happens is this:
Restart()
- Stop()
lock
.... do work
1) unlock
- exit Stop();
- Start()
2) lock
..... do work
unlock
- exit Start()
- exit Restart

What happens between 1) and 2) ? Can the state be corrupted?

If the state between 1) and 2) must not be modified, then Restart() must establish its own lock.
arthur83
arthur83
Quote:
Original post by Antheus
If the state between 1) and 2) must not be modified, then Restart() must establish its own lock.


Sorry, I ment that Start, Stop and thereby Restart uses the same shared resource. But check this out (notation: : ):
1: Restart()
1: In Restart: Stop()
1: In Restart: (After Stop())
2: Start()
2: In Start: Allocating resource
1: In Restart: Start()
1: In Start: Allocating resource

Is this not thread-safe or is it just bad design?
SunTzu
SunTzu
There's a few things to note here:

- if the threads only read data and don't modify it, or work on independent data, there's no problem.

- otherwise, if Stop() doesn't care whether the shared data has changed since Start() was called from this thread, there's no problem (because Start() and Stop() are each threadsafe).

- on the other hand, if Stop() needs the shared data to still be the same as it was when Start() was called, Restart() will not be thread safe unless you explicitly make it so.

I'm not completely sure I follow your example in your most recent post, but if it says what I think you're trying to say, you're pretty much proving the third point, ie. Restart() is not threadsafe and it sounds like it needs to be.

You can probably make it safe by wrapping Restart() in a critical section, which by the sound of things will involve rearranging your Start() and Stop() functions somewhat...

void Start(){Lock( &critsec );DoStart(); // ie. separate the behaviour from the lockingUnlock( &critsec );}void Stop(){Lock( &critsec );DoStop(); // ie. same againUnlock( &critsec );}void Restart(){Lock( &critsec );DoStop();DoStart();Unlock( &critsec );}void DoStart(){// whatever - assume you already have the lock}void DoStop(){// whatever - assume you already have the lock}


... but without seeing exactly what you're doing, it's hard to say if that's exactly what you need; still I hope you get the idea. Note that DoStart() and DoStop() now make an assumption about safety, so you may need to ensure they don't get called except through Start(), Stop(), and Restart() (for example making them private if that's possible).

In any case, to answer the original question: no, just because every function you call is threadsafe, does not automatically mean you yourself are threadsafe.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.