Qt-interest Archive, August 2007
Thread misunderstanding
Message 1 in thread
Hi all,
I am trying to use QThread and QSemaphore for the first time and it seems
that I don't understand very well this stuff.
My Thread is derived of a QThread but has a pointer to a semaphore m_Sem.
The run function is reimplemented and looks like this :
{
m_Sem->acquire();
[do my stuff]
m_Sem->release();
}
The calling function looks like that
{
QSemaphore sem( threadNum );
for ( int i=0;i< m_WidgetList.size();i++ ) {
myThread th( &sem,... );
th.start();
}
QProgressBar b( this );
b.setMaximum( 0 );
b.setMinimum( 0 );
b.show();
while ( ! sem.tryAcquire( threadNum ) )
{
QApplication::processEvents();
}
}
When I run this code, I got a segfautl and the message that a least one
running thread has been destroyed though my idea was that the loop at the
end of the function would wait for every thread to be finished before
exiting.
What I am doing wrong here ?
TIA
Alain
--
[ signature omitted ]
Message 2 in thread
in my program i used:
QApplication::processEvents(QEventLoop::WaitForMoreEvents)
cheers seb
On Tuesday 07 August 2007 20:28:22 denebet wrote:
> Hi all,
>
> I am trying to use QThread and QSemaphore for the first time and it seems
> that I don't understand very well this stuff.
>
> My Thread is derived of a QThread but has a pointer to a semaphore m_Sem.
> The run function is reimplemented and looks like this :
> {
> m_Sem->acquire();
>
> [do my stuff]
>
> m_Sem->release();
> }
>
> The calling function looks like that
> {
> QSemaphore sem( threadNum );
> for ( int i=0;i< m_WidgetList.size();i++ ) {
> myThread th( &sem,... );
> th.start();
> }
> QProgressBar b( this );
> b.setMaximum( 0 );
> b.setMinimum( 0 );
> b.show();
> while ( ! sem.tryAcquire( threadNum ) )
> {
> QApplication::processEvents();
> }
> }
>
> When I run this code, I got a segfautl and the message that a least one
> running thread has been destroyed though my idea was that the loop at the
> end of the function would wait for every thread to be finished before
> exiting.
> What I am doing wrong here ?
>
> TIA
>
> Alain
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body. List archive and information:
> http://lists.trolltech.com/qt-interest/
--
[ signature omitted ]
Message 3 in thread
On Tuesday 07 August 2007, denebet wrote:
> Hi all,
>
> I am trying to use QThread and QSemaphore for the first time and it seems
> that I don't understand very well this stuff.
>
Ok. I'll give it a shot.....
> My Thread is derived of a QThread but has a pointer to a semaphore m_Sem.
> The run function is reimplemented and looks like this :
> {
> m_Sem->acquire();
Doh! Do *NOT* use semaphores if you need to protect data in the same process.
Use Mutexes instead. A Mutex "lives" in userspace and is meant for this
purpose. A Semaphore is used the same but protects data across *processes* In
this case, the semaphore exists at kernel level, making it very expensive to
set and release. For this purpose, a call to kernel level has to be made.
>
> [do my stuff]
>
> m_Sem->release();
> }
>
> The calling function looks like that
> {
> QSemaphore sem( threadNum );
> for ( int i=0;i< m_WidgetList.size();i++ ) {
> myThread th( &sem,... );
> th.start();
> }
> QProgressBar b( this );
> b.setMaximum( 0 );
> b.setMinimum( 0 );
> b.show();
> while ( ! sem.tryAcquire( threadNum ) )
> {
> QApplication::processEvents();
> }
> }
>
> When I run this code, I got a segfautl and the message that a least one
> running thread has been destroyed though my idea was that the loop at the
> end of the function would wait for every thread to be finished before
> exiting.
> What I am doing wrong here ?
Wow! Ehm... This is not easily said. In a multi-threaded app, the heap is used
as shared memory between threads. Every object created there (the
new-operator does that) is accessible by pointer-passing. Inside such an
object, a method can exist, protected by a Mutex.
Or in (pseudo)code..
----------[ Begin ]------------------
----------[ Shared Object ]----------
class sharedObject
{
public:
sharedObject();
~sharedObject();
void callMethod();
private:
QMutex *pMutex;
};
sharedObject::sharedObject()
{
pMutex = new QMutex();
}
sharedObject::~sharedObject()
{
}
void sharedObject::callMethod
{
if( pMutex->tryLock() )
{
// Do your stuff
pMutex->unLock();
}
}
----------[ Threaded Object ]----------
class MyThread : public QThread
{
Q_OBJECT
public:
MyThread( sharedObject *pObject );
void run();
private:
sharedObject *m_pSharedObject;
};
MyThread::MyThread( sharedObject *pObject )
: m_pSharedObject( pObject )
{
// Initialisation here
}
void MyThread::run()
{
if( m_pSharedObject )
{
m_pSharedObject->callMethod();
}
exec(); <<-- Very important if you use signals / slots
}
----------[ Main ]----------
int main( int argc, char *argv[] )
{
QCoreApplication coreApp( argc, argv );
sharedObject *pSharedObject = new sharedObject();
myThread *pMyThread = new MyThread( pSharedObject );
pMyThread->start();
coreApp.exec();
}
----------[ End ]------------------
I'm sure there are a million ways to do this, but this has been proven working
in many projects I did.
Hope this helps..
>
> TIA
>
> Alain
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body. List archive and information:
> http://lists.trolltech.com/qt-interest/
--
[ signature omitted ]
Message 4 in thread
Peter M. Groen wrote:
>
> Wow! Ehm... This is not easily said. In a multi-threaded app, the heap is
> used as shared memory between threads. Every object created there (the
> new-operator does that) is accessible by pointer-passing. Inside such an
> object, a method can exist, protected by a Mutex.
>
> Or in (pseudo)code..
>
> ----------[ Begin ]------------------
>
> ----------[ Shared Object ]----------
>
> class sharedObject
> {
> public:
> sharedObject();
> ~sharedObject();
>
> void callMethod();
>
> private:
> QMutex *pMutex;
> };
>
> sharedObject::sharedObject()
> {
> pMutex = new QMutex();
> }
>
> sharedObject::~sharedObject()
> {
> }
>
> void sharedObject::callMethod
> {
> if( pMutex->tryLock() )
> {
> // Do your stuff
>
> pMutex->unLock();
> }
> }
>
> ----------[ Threaded Object ]----------
>
> class MyThread : public QThread
> {
> Q_OBJECT
> public:
> MyThread( sharedObject *pObject );
> void run();
>
> private:
> sharedObject *m_pSharedObject;
> };
>
> MyThread::MyThread( sharedObject *pObject )
> : m_pSharedObject( pObject )
> {
> // Initialisation here
> }
>
> void MyThread::run()
> {
> if( m_pSharedObject )
> {
> m_pSharedObject->callMethod();
> }
> exec(); <<-- Very important if you use signals / slots
> }
>
> ----------[ Main ]----------
>
> int main( int argc, char *argv[] )
> {
> QCoreApplication coreApp( argc, argv );
> sharedObject *pSharedObject = new sharedObject();
>
> myThread *pMyThread = new MyThread( pSharedObject );
> pMyThread->start();
>
> coreApp.exec();
> }
>
> ----------[ End ]------------------
>
> I'm sure there are a million ways to do this, but this has been proven
> working in many projects I did.
>
> Hope this helps..
>
Thanks for your detailed answer. Please forgive me if I am stupid but I
understand that your code is made so that whatever the number of MyThread
objects created there will be only one callMethod running at the same time.
Is this right ?
My goal is a little bit different : I want to allow a fixed number of
threads running at the same time (they work on different files) and wait
that every thread is finished before the function where they are created
exits (in fact, each thread resizes a picture, I want to display a progress
bar during this time and when every thread is finished, hide the progress
bar and make my soft go on).
Regards,
Alain
--
[ signature omitted ]
Message 5 in thread
On Wednesday 08 August 2007, denebet wrote:
------------[ Begin ]---------------------
> Thanks for your detailed answer. Please forgive me if I am stupid but I
> understand that your code is made so that whatever the number of MyThread
> objects created there will be only one callMethod running at the same time.
> Is this right ?
Not knowing something comes from lack of knowledge, not stupidity. Stupidity
is *thinking* you know everything and not trying to learn something.....
In my example I only tried to explain *where* the mutex lives, not to make a
method run single or locked (*That* would kill the threading idea, wouldn't
it?).. Normally you lock a mutex the moment you start changing private
members of the class and releasing them immediately afterwards to avoid race
conditions. ( See the "Dining Philosophers Problem" ).
I only created one thread, but you can imagine it is possible to use multiple.
When a thread tries to lock a mutex that is locked from another thread, it
will sleep. Everytime the scheduler is activating this thread, it tries
locking the mutex until it succeeds.. (When it tries to lock a mutex that was
lock by itself, it causes a "deadlock". This happens when you forget to
unlock the mutex when you're done. Luckily, Qt-checks for that when compiled
in Debug mode and asserts..)
Or in our callMethod()
{
// Do a *lot* of heavy work....
pMutex->lock(); <<== If locking fails, it waits until it can...
m_pPrivMem = <Some value>;
pMutex->unlock();
}
>
> My goal is a little bit different : I want to allow a fixed number of
> threads running at the same time (they work on different files) and wait
> that every thread is finished before the function where they are created
> exits (in fact, each thread resizes a picture, I want to display a progress
> bar during this time and when every thread is finished, hide the progress
> bar and make my soft go on).
>
Ehm.. Ok. I hope you are not updating the GUI from the thread, because that is
not (yet) possible... (It would explain your segfaults..) By using a shared
object in the main thread, it can update the GUI (Which also exists in the
main thread). Try reading something about signals and slots between threads
in the Qt-Assistant. It's actually quite good.
Letting the "Soft go on" could be done by an object creating all the threads,
catching their signals if they are finished doing their stuff, removing the
thread-objects and signalling the application that it is finished..
For now: ... Have fun! :)
--
[ signature omitted ]
Message 6 in thread
Peter M. Groen wrote:
>
> Ehm.. Ok. I hope you are not updating the GUI from the thread, because
> that is not (yet) possible... (It would explain your segfaults..) By using
> a shared object in the main thread, it can update the GUI (Which also
> exists in the main thread). Try reading something about signals and slots
> between threads in the Qt-Assistant. It's actually quite good.
>
> Letting the "Soft go on" could be done by an object creating all the
> threads, catching their signals if they are finished doing their stuff,
> removing the thread-objects and signalling the application that it is
> finished..
Ok, thanks for you explanations.
Alain
--
[ signature omitted ]