PDA

View Full Version : Does it make sense to use a QSemaphore for acessing data inside the same thread?



Momergil
6th January 2014, 15:21
Hello!

Suppose I have a given varible, such as a boolean working as a flag, that need to be both written and read in the same thread. Is it possible for the some kind of problem happen because of the possibility of this variable has its value read and changed "at the same time" inside the same thread? And when its value is altered by a signal emitted from another thread? (For example, I create a QThread based class that, when the finished() signal is emitted, it alters a boolean flag on its parent indicating that the thread has stoped running, but the value of that boolean flag may be read at any time by the parent object to verify that state).

Just to give a context, I'm trying to know this because I have a similar situation as described inside the parenthesis above, but for now Im using isRunning() to verify for the current's thread state and this is not very good, since the pointer to my thread may be deleted ("delete poThread") at any time, what makes necessary to use QSemaphores, what I want to avoid).


Hope I was clear enough :)


Momergil

anda_skoa
6th January 2014, 23:22
I don't think I fully understand the question, but if you have any data that is accessed by more than one thread, then this access has to be protected against concurrency. Easiest way to do that is using QMutex.

Not sure why you bring QSemaphore up, though, hence my guess that I don't understand what your actual problem is.

Cheers,
_

Momergil
7th January 2014, 00:22
Hello anda_skoa,

yeah, I though I didn't exaplain it very well... So let me "reshow" my doubt:

I know that when the same data is accessed by different threads, that data need to be protected by a mutex (as you mentioned above); no problems here. But what about when a variable is accessed by the same thread (and for different funcionality: reading and writting)? So is my situation as mentioned above: I want to store the current situation of a thread (if it's running or not) in a boolean variable, whose value may change when the thread's finished() signal is emitted. In this case, need I to protect the reading of that variable (with a QSemaphore, I guess)? Or since the slot connected to that thread's finished() signal is in the same thread where the reading procedure will occurr, that is not needed?


If this new explanation don't work, I post a example code :)


Momergil

d_stranz
7th January 2014, 02:05
If you have only one thread, then it is impossible for the value of any variable to change in between writing it and reading it. If you write a value to the variable, it will never change no matter how many times you read it, until you write it again.

I think you don't understand the concept of a thread. It is a single continuous string of execution of instructions from beginning to end. It doesn't matter whether you have branches or loops, signals, slots, whatever, only one instruction ever gets executed at any time. The situation you are imagining, where a variable might get changed in between writing and reading it, within the same thread just simply can't happen. If the read instruction follows the write instruction in the execution sequence, that value that is read will be the value that was just written. There's no way for some gremlin to sneak in and change the value.

So there is absolutely no need for semaphores or any other kind of access protection in a single-threaded program.

But as soon as you create a program with more than one thread, and you share a memory location among them, then if any thread writes to the location, then you must protect it.

Momergil
7th January 2014, 02:33
Hello d_stranz,

well, so I was guessing :) And I imagine that the fact the slot that changes a varible's value was connected to a signal from another thread don't change the situation, correct?

Well, that was my doubt =]

Thanks,

Momergil

d_stranz
7th January 2014, 04:29
If your app has only one thread, then all the signals and slots are in that thread. There is no between-threads connection. There is no magic about signals and slots. They are just C++ method calls underneath all the Qt wrappings.

anda_skoa
7th January 2014, 11:50
But what about when a variable is accessed by the same thread (and for different funcionality: reading and writting)?

It really doesn't matter how it is used by a thread, the only thing that matters is if it is used by more than one thread.



So is my situation as mentioned above: I want to store the current situation of a thread (if it's running or not) in a boolean variable, whose value may change when the thread's finished() signal is emitted. In this case, need I to protect the reading of that variable (with a QSemaphore, I guess)?

If the variable lives in the main thread's context and is only changed by slots connected to the second thread's signals, e.g. set to true when started() is emitted and set to false when finished() is emitted, then you don't need any protection. This is because the cross-thread signal/slot connection, by default, invokes the slot in the thread of the receiver object, which in your case would be the main thread. So all access to the variable would come from the same there, ergo no protection needed.

Cheers,
_

Momergil
8th January 2014, 01:03
Thanks anda_skoa and d_stranz; problem solved :)


Momergil