Calling non-reentrant code from Multiple threads.



  • My GUI thread creates two threads of type "MyThread" which is a QThread subclass. The run function of these threads uses a non-reentrant function call. I want to make sure that this function call is used in a serialized manner, i.e only one of the instances of MyThread makes this call, the other waits for the function call to return. I wrote the run function as below(sMutex is a static member of MyThread):
    @void MyThread::run()
    {
    sMutex.lock();
    NonReentrantFuncCall();
    sMutex.unlock();

    emit done();
    }@
    This does not work for me. Is this the right approach?



  • Hello,
    take a look at "Thread-Safety":http://doc.qt.nokia.com/4.7/threads-reentrancy.html. I think it will help you :)



  • The mutex should be locked inside the re-entrant function..



  • Hi,

    By "not work for me", which part doesn't work? The locking around the function looks ok, although I agree with @maxpayne the locking should be inside the function. You might have problems with the emit if you don't have an event loop running for the thread. I think you need to have an exec() in the run function somewhere.

    Steve



  • emitting signals is no problem, but the connect statement must be correct (QueuedConnection!).
    Please show us some more code (creation and conbnect of the thread) and describe your problem a bit more precisely...



  • Side note: if you're using the Qt naming convention, "non reentrant" means that it's not safe to call from multiple threads at all, no matter of serializing accesses (to shared data) using mutexes.

    http://developer.qt.nokia.com/wiki/Threads_Events_QObjects#ee68e5b99222bbc29a480fcb0d1d6ee2
    http://doc.qt.nokia.com/latest/threads-reentrancy.html



  • [quote author="Gerolf" date="1305893735"]emitting signals is no problem, but the connect statement must be correct (QueuedConnection!).
    Please show us some more code (creation and conbnect of the thread) and describe your problem a bit more precisely...[/quote]

    @// GUI thread
    MyThread *thread = new MyThread();

    connect(thread, SIGNAL(done()),
    this, SLOT(Loaded()));

    thread->start();
    @
    @void MyThread::run()
    {
    sMutex.lock();
    NonReentrantFuncCall();
    sMutex.unlock();

    emit done();
    this->exec();
    }@

    Since the emit is in a different thread than the receiver and I have created an automatic connection, I need the event loop. But the above signal does not reach the slot. Is it due to the fact that the exec call is after the emit? But I can not move it above the emit as the emit will never be called. Also when do I call the exit().



  • [quote author="spsingh" date="1305899696"]
    Since the emit is in a different thread than the receiver and I have created an automatic connection, I need the event loop. But the above signal does not reach the slot. Is it due to the fact that the exec call is after the emit? But I can not move it above the emit as the emit will never be called. Also when do I call the exit().
    [/quote]

    Wrong, I think. The emitting object has the same thread affinity as your receiving GUI thread, no matter if the emit was triggered from another thread. That is why the reimplement-QThread method is trickly when using signals and slots.



  • Are you sure your code is not getting stuck while locking the mutex ?



  • [quote author="spsingh" date="1305899696"]
    Since the emit is in a different thread than the receiver and I have created an automatic connection, I need the event loop. But the above signal does not reach the slot. Is it due to the fact that the exec call is after the emit? But I can not move it above the emit as the emit will never be called. Also when do I call the exit().
    [/quote]

    The snippet is fine, but

    you need an event loop in the receiver's thread, NOT in that thread. Calling exec() there seems wrong

    what does NonReentrantFuncCall(); do exactly?



  • [quote author="Andre" date="1305925948"]
    Wrong, I think. The emitting object has the same thread affinity as your receiving GUI thread, no matter if the emit was triggered from another thread. That is why the reimplement-QThread method is trickly when using signals and slots. [/quote]

    Nope. It works that way. See http://developer.qt.nokia.com/wiki/Threads_Events_QObjects#913fb94dd61f1a62fc809f8d842c3afa the note about the wrong documentation.



  • [quote author="peppe" date="1305941696"]
    [quote author="Andre" date="1305925948"]
    Wrong, I think. The emitting object has the same thread affinity as your receiving GUI thread, no matter if the emit was triggered from another thread. That is why the reimplement-QThread method is trickly when using signals and slots. [/quote]

    Nope. It works that way. See http://developer.qt.nokia.com/wiki/Threads_Events_QObjects#913fb94dd61f1a62fc809f8d842c3afa the note about the wrong documentation.

    [/quote]
    I stand corrected. Thanks.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.