Solved Question about QThread and how thread work in general.
-
@Kent-Dorfman Your right, I did not precise what is my project, so here is for you:
I am trying to make a bio-mimetic (in apearance, at least) robotical arm, wich is requiring around 20 smart servo to operate the hand. I'm using a raspberry pi 3B+ to operate everything. Since every servo cost $50 usd, I'm planning to make a loop that verify every servo and emit an emergency signal if something is going wrong. I'm planning to also use this verification as a feedback that would update the virtual representation of the force and position of the member. Since I'm more a guy that just get admitted in mechanical engineering that someone with a great knowledge of electronics, I'm planning to stick on the raspberry pi until I got some result out of this, but perhaps I will used a dedicated micro-controller for the communication and this loop. However, I'm planning to completed my personal exploration of c/c++ before doing so.
-
Hi,
@Factao wow! very beautiful project.
I think I could learn from you ;)Technically @Kent-Dorfman is right, You shouldn't care about multiple simultaneous reads because changes can become a problem.
Anyway, when a function, that uses variables member, starts I prefer, if is possible, copying members (Note: only variables that can be changed by external class, for example via setXXXX functions) and I do this under lock and unlock.
That's because I normally want to have a constant instant photo for all during of function.
To avoid deadlock, if is possible, I prefer using QMutex with moderation and, always if is possible, only for changing and reading variables. Always to avoid deadlock I use QMutex to protect all body function very rarely. This is how I use QMutex, but doesn’t mean is right way, is right for me.Qt offers other classes for thread synchronization, for these I suggest you to read the manual.
Regards
Paolo -
@Factao said in Question about QThread and how thread work in general.:
I'm using slots and signals in order to command the worker thread, but this last one, when not doing a specific task, is within a loop, constantly reading value from a servo and saving them. Since there is a lot of variable that change frequently, emitting a signal for every one of them might slow the application down, due to how signal/slot work.
The signal-slot connections work very similarly to how you'd serialize access with a mutex, as a matter of fact they do exactly that - serialize access to the event loop through a mutex. So unless you can prove that emission and handling of signals is a bottleneck, that concern is moot. The big advantage, however, is that thread access is defined strictly and clearly for each
QObject
involved, so it makes for convenient and fast coding. -
Hi @kshegunov,
I'm Qt developer only for few years, so I’m quite newbie ;)
Is there difference using signals&slots or direct method between threads with different priority?
I think yes but I’m not sure.
Thanks -
@CP71 the main difference is, that your signal argument, if it is a struct or class, needs to have a copy constructor.
Where as with direct mutex lock, you simply lock the data block, access it and unlock it.
-
@J.Hilk
Thank you,
yes this I know, my question was incomplete, sorry.
but I’m thinking about response time. -
Well, thank you everyone, thank you. I think that we can conclude this topic. Once again, thank you.
@CP71 said in Question about QThread and how thread work in general.:
I think I could learn from you ;)
If you need help on a subject that is more mechanical or mathematical, don't hesitate, I will be more than happy to help you back.
-
@Factao
Sure, count on it.
Thanks -
@Factao said in Question about QThread and how thread work in general.:
int m_something;// private element of class
int class::returnSomething() const
{
mutex.lock()
return m_something;
mutex.unlock()
};Hi Factao, just give you a little hint abour QMutex usage, the easiest way to deal with QMutex, is to use QMutexLocker, to avoid having mutex lock when leaving function:
int class::returnSomething() const { QMutexLocker lock(&mutex); Q_UNUSED(lock) // just to remove warnings return m_something; };
At function begin, mutex will be locked, and when lock is distroyed (by living function) mutex will be released.
This will avoid having deadlocks!But as writen in other comments, using Signals/Slots mechanisme to exhange information between object in different thread is the most easiest way. You don't have to deal with mutex. The disadvantage is that will have shadow copies of your data, so if there are big amonth of data, this could be a problem.
Hope this will help you
-
@KroMignon said in Question about QThread and how thread work in general.:
will have shadow copies of your data
For implicitly shared types (Qt types) - shallow copies, which may or may not, depending on the use, become deep copies.
@CP71 said in Question about QThread and how thread work in general.:
Hi @kshegunov,
Is there difference using signals&slots or direct method between threads with different priority?Priority has nothing to do with anything. The thread priority is a hint to the scheduler how large a time slot to dispense.
-
@kshegunov said in Question about QThread and how thread work in general.:
Priority has nothing to do with anything. The thread priority is a hint to the scheduler how large a time slot to dispense.
Actually, in some operating systems (e.g. in Linux via sched_setscheduler) it's possible to change scheduler for particular thread to real-time (in Linux SCHED_FIFO or SCHED_RR). Real-time thread have static priorities which has deeper effect on time slots than dynamic ("nice") priorities
(QThread::IdlePriority is internally implemented via SCHED_IDLE on Linux, other options use default scheduler with dynamic priorities)
-
Perhaps, but I don't see an implication for the case of signal-slot connections vs direct synchronization ... at the end of the day the former still uses a mutex to serialize access to the queued events ...