[Paraview] Plugin with own thread
Michael Jackson
mike.jackson at bluequartz.net
Thu Mar 10 11:49:22 EST 2011
There was a big discussion on this on the qt-interest mailing list back in December I think. Basically a QThread "manages" a native thread on the operating system but does NOT reside on that thread itself.
Rather than trying to explain it I'll refer you to one of the Authors of the QThread class and how HE says it should be done.
http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/
___________________________________________________________
Mike Jackson www.bluequartz.net
Principal Software Engineer mike.jackson at bluequartz.net
BlueQuartz Software Dayton, Ohio
On Mar 10, 2011, at 11:14 AM, Utkarsh Ayachit wrote:
> I replied prematurely without realizing the currentThreadId() is a
> static method. So have you changed the "connect" to use a queued
> connection or not?
>
> Utkarsh
>
> On Thu, Mar 10, 2011 at 8:05 AM, Utkarsh Ayachit
> <utkarsh.ayachit at kitware.com> wrote:
>> If you look at http://doc.qt.nokia.com/latest/qobject.html#thread
>>
>> you'll see that QObject::thread() returns the thread to which the
>> object belongs, not the thread in which the code is being executed.
>>
>> Utkarsh
>>
>> On Thu, Mar 10, 2011 at 12:35 AM, Stephan Rogge
>> <Stephan.Rogge at tu-cottbus.de> wrote:
>>> Hello Utkarsh,
>>>
>>> thank you very much for the quick response and thanks for pointing me
>>> on the QThread documentation. Regarding to the QT doc I realized a
>>> direct connection here, which leads to an immediately processing of
>>> Trigger().
>>>
>>> Well, my assumption was indeed wrong. So I went back to my code and
>>> include some debug outputs to clarify which thread processes the
>>> pqMyApplicationStarter::Trigger() method. In order to get these
>>> information I output the current thread Ids of my plugin (in
>>> onStartup and Trigger) ...
>>>
>>> void pqMyApplicationStarter::onStartup()
>>> {
>>> ...
>>> qWarning() << "Message from pqMyApplicationStarter:
>>> Application Started
>>> (" << this->thread()->currentThreadId() << ")";
>>>
>>> }
>>>
>>> void pqMyApplicationStarter:: Trigger()
>>> {
>>> ...
>>> qWarning() << "pqMyApplicationStarter::Trigger():
>>> " << this->thread()->currentThreadId();
>>>
>>> }
>>>
>>> and in my external thread (Thread::run).
>>>
>>> void Thread::run()
>>> {
>>> running = true;
>>>
>>> while( running )
>>> {
>>> qWarning() << "Thread::run(): " <<
>>> currentThreadId();
>>>
>>> // Fire the signal
>>> emit UpdatedData();
>>>
>>> qWarning() << "Invocation done";
>>> }
>>> }
>>>
>>> This lead to the following output:
>>>
>>> Message from pqMyApplicationStarter: Application Started ( 0x1514 )
>>> Thread::run(): 0x123c
>>> pqMyApplicationStarter::Trigger(): 0x1514
>>> Invocation done
>>>
>>> And here I a new question arises: It seems to be, that Trigger is
>>> invoked in my external thread and waits for return but is processed
>>> in the plugin thread. Is that right?
>>>
>>>
>>> Thanks again,
>>>
>>> Best regards,
>>> Stephan
>>>
>>>
>>> -----Ursprüngliche Nachricht-----
>>> Von: Utkarsh Ayachit [mailto:utkarsh.ayachit at kitware.com]
>>> Gesendet: Mittwoch, 9. März 2011 17:25
>>> An: Stephan Rogge
>>> Cc: paraview at paraview.org
>>> Betreff: Re: [Paraview] Plugin with own thread
>>>
>>> You might want to read
>>> http://doc.qt.nokia.com/latest/threads-qobject.html especially the
>>> section about signal/slots and threads.
>>>
>>> In your code, contrary to what you expect, Trigger() is being called
>>> in your thread and not the "main thread" and hence the issues you
>>> might be seeing. If you simply change the connection to use a
>>> Qt::QueuedConnection you'd get the desired effect.
>>>
>>> Utkarsh
>>>
>>> On Wed, Mar 9, 2011 at 8:10 AM, Stephan Rogge
>>> <Stephan.Rogge at tu-cottbus.de> wrote:
>>>> Hello,
>>>>
>>>>
>>>>
>>>> after reading the tutorials and How-to’s for writing ParaView Plugins I’ve
>>>> started with the Autostart-Example project. My goal was to create a plugin
>>>> which is executed in an external thread. It might happens that I need this
>>>> in the near future.
>>>>
>>>>
>>>>
>>>> Well, it works quit well, I guess. But to avoid some errors and
>>>> miss-behaviors I need a confirmation that I am on the right way.
>>>>
>>>>
>>>>
>>>> My approach is to use the signal-slot-pattern to communicate between the
>>>> main thread of ParaView and my own plugin-thread. The class
>>>> pqMyApplicationStarter represents the ParaView-plugin (which is running in
>>>> the main thread of ParaView?). There is an object in this class which
>>>> executes a loop within an external thread ( class Thread ), which extends
>>>> QThread.
>>>>
>>>>
>>>>
>>>> As I read somewhere that vtk isn’t implemented threaded-safe at all (at
>>>> least the rendering stuff) I decided to do all render calls in
>>>> pqMyApplicationStarter. When the UpdatedData()signal is fired the active
>>>> view needs to re-rendered.
>>>>
>>>>
>>>>
>>>> The question I want to ask is very simple: Is this the right / best way to
>>>> create a thread and communicate with it via signals?
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> /////////////// Thread.h ////////////////////////////
>>>>
>>>> class Thread : public QThread
>>>>
>>>> {
>>>>
>>>> Q_OBJECT
>>>>
>>>> public:
>>>>
>>>> Thread(QObject* parent = 0);
>>>>
>>>> virtual ~Thread();
>>>>
>>>> virtual void run();
>>>>
>>>> signals:
>>>>
>>>> void UpdatedData();
>>>>
>>>> };
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> void Thread::run()
>>>>
>>>> {
>>>>
>>>> running = true;
>>>>
>>>>
>>>>
>>>> while( running )
>>>>
>>>> {
>>>>
>>>> // Sleep awhile
>>>>
>>>> msleep( 800 );
>>>>
>>>> // Fire the signal
>>>>
>>>> emit UpdatedData();
>>>>
>>>> }
>>>>
>>>> }
>>>>
>>>> /////////////////////////////////////////////////////
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> /////////////// pqMyApplicationStarter //////////////
>>>>
>>>> class pqMyApplicationStarter : public QObject
>>>>
>>>> {
>>>>
>>>> Q_OBJECT
>>>>
>>>> typedef QObject Superclass;
>>>>
>>>>
>>>>
>>>> public:
>>>>
>>>> pqMyApplicationStarter(QObject* p=0);
>>>>
>>>> ~pqMyApplicationStarter();
>>>>
>>>>
>>>>
>>>> // Callback for startup.
>>>>
>>>> void onStartup();
>>>>
>>>>
>>>>
>>>> public slots:
>>>>
>>>> void Trigger();
>>>>
>>>> };
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> void pqMyApplicationStarter::onStartup()
>>>>
>>>> {
>>>>
>>>> myThread = new Thread();
>>>>
>>>> myThread->start();
>>>>
>>>>
>>>>
>>>> pqActiveObjects::instance().connect( myThread,
>>> SIGNAL(UpdatedData()),
>>>> this, SLOT(Trigger()) );
>>>>
>>>> }
>>>>
>>>>
>>>>
>>>> void pqMyApplicationStarter::Trigger()
>>>>
>>>> {
>>>>
>>>> pqActiveObjects* object = &(pqActiveObjects::instance());
>>>>
>>>> pqView* view = object->activeView();
>>>>
>>>>
>>>>
>>>> if (view)
>>>>
>>>> {
>>>>
>>>> view->render();
>>>>
>>>> }
>>>>
>>>>
>>>>
>>>> view = NULL;
>>>>
>>>> }
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> Thanks a lot.
>>>>
>>>>
>>>>
>>>> Cheers,
>>>>
>>>> Stephan
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> Powered by www.kitware.com
>>>>
>>>> Visit other Kitware open-source projects at
>>>> http://www.kitware.com/opensource/opensource.html
>>>>
>>>> Please keep messages on-topic and check the ParaView Wiki at:
>>>> http://paraview.org/Wiki/ParaView
>>>>
>>>> Follow this link to subscribe/unsubscribe:
>>>> http://www.paraview.org/mailman/listinfo/paraview
>>>>
>>>>
>>>
>>> _______________________________________________
>>> Powered by www.kitware.com
>>>
>>> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>>>
>>> Please keep messages on-topic and check the ParaView Wiki at: http://paraview.org/Wiki/ParaView
>>>
>>> Follow this link to subscribe/unsubscribe:
>>> http://www.paraview.org/mailman/listinfo/paraview
>>>
>>
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the ParaView Wiki at: http://paraview.org/Wiki/ParaView
>
> Follow this link to subscribe/unsubscribe:
> http://www.paraview.org/mailman/listinfo/paraview
More information about the ParaView
mailing list