Results 1 to 7 of 7

Thread: Emitting a signal is corrupting data

  1. #1
    Join Date
    Nov 2010
    Posts
    57
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    4
    Thanked 1 Time in 1 Post

    Default Emitting a signal is corrupting data

    I am creating a "new" struct object and sending the pointer through a signal about 100 times per second. This signal is connected to a slot in a different thread. If I run the app with the first code snip-it, the data is corrupted between 0 and 10 000 sent signals. If I run it with the second code snip-it (I just wanted to do a little debugging) it never gets corrupted.

    Any Ideas why this is happening? and if there is a nicer solution than using a conditional statement?

    Corrupted after some time:
    Qt Code:
    1. struct MyStruct
    2. {
    3. MyStruct(unsigned int handle, std::string const& aName, std::string const& bName) :
    4. _handle(handle),
    5. _aName(aName),
    6. _bName(bName)
    7. {
    8. }
    9.  
    10. unsigned int _handle;
    11. std::string _aName;
    12. std::string _bName;
    13. };
    To copy to clipboard, switch view to plain text mode 

    Doesn't get corrupted:
    Qt Code:
    1. struct MyStruct
    2. {
    3. MyStruct(unsigned int handle, std::string const& aName, std::string const& bName) :
    4. _handle(handle),
    5. _aName(aName),
    6. _bName(bName)
    7. {
    8. if(_bName.at(0) < 'A' || _bName.at(0) > 'z')
    9. {
    10. qDebug() << "ERROR: " << _bName.c_str();
    11. }
    12. if(_aName.size() > 0 && (_aName.at(0) < 'A' || _aName.at(0) > 'z'))
    13. {
    14. qDebug() << "ERROR: " << _aName.c_str();
    15. }
    16. }
    17.  
    18. unsigned int _handle;
    19. std::string _aName;
    20. std::string _bName;
    21. };
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Nov 2010
    Posts
    315
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo
    Thanked 53 Times in 51 Posts

    Default Re: Emitting a signal is corrupting data

    You have problem with multi-threading! You did something wrong there but you didn't show anything about that so it is impossible to say what is wrong.

  3. #3
    Join Date
    Nov 2010
    Posts
    57
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    4
    Thanked 1 Time in 1 Post

    Default Re: Emitting a signal is corrupting data

    Possibly, that is what I was trying to debug initially, but why would an "if" statement fix the problem?

    In the slot I do this:
    Qt Code:
    1. void Outer::receiveStruct(MyStruct *mStruct)
    2. {
    3. QWriteLocker locker(&lock);
    4. _mStructs.push_back(mStruct);
    5.  
    6. }
    To copy to clipboard, switch view to plain text mode 

    lock is: mutable QReadWriteLock lock;

    Then the objects are taken like so:
    Qt Code:
    1. std::list<MyStruct *> Outer::getStructs()
    2. {
    3. QReadLocker locker(&lock);
    4. std::list<CafRequest*> tmpList = _mStructs;
    5. _mStructs.clear();
    6. return tmpList;
    7. }
    To copy to clipboard, switch view to plain text mode 

    I used to do this but it didn't seem to make any difference:
    Qt Code:
    1. std::list<MyStruct *>* Outer::getStructs()
    2. {
    3. return &_mStructs;
    4. }
    To copy to clipboard, switch view to plain text mode 

    The function that calls getStructs deletes the objects.

  4. #4
    Join Date
    Nov 2010
    Posts
    315
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo
    Thanked 53 Times in 51 Posts

    Default Re: Emitting a signal is corrupting data

    Still this gives almost nothing.
    At least it seems you did something wrong.
    Emitting and reciving in slot a pointer value is disturbing solution especially in mutithreding case.
    I also suspect that you are using lock in wrong way.

    The safest way to solve mutithreading producer consumer problem in Qt is:
    Define QObjects class representing producer and consumer (do NOT subclass QThread!!!).
    Create needed QThreads and move instances of producer (QObject::moveToThread) and consumer to proper threads.
    Connect signal of producer to respective slot of consumer.
    To pass by value custom structure by a signal slot mechanism declare and define meta data for this custom type (instruction can be found in documentation).
    Use of default Qt type is recommended (QList, QVector insted std::list and std:vector).
    Note that consumer should be faster then producer or event queue of consumer may grow.

  5. The following user says thank you to MarekR22 for this useful post:

    pan (7th July 2011)

  6. #5
    Join Date
    Nov 2010
    Posts
    57
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    4
    Thanked 1 Time in 1 Post

    Default Re: Emitting a signal is corrupting data

    Thanks for your reply MarekR22, its much appreciated.

    I can't give you all the code, I've just tried to break it down and was asking for ideas on what I saw as the main problem. I have done most of what you suggested, apart from what I have noted below.

    Emitting and reciving in slot a pointer value is disturbing solution especially in mutithreding case.
    I will try sending variables rather than a pointer.

    Use of default Qt type is recommended (QList, QVector insted std::list and std:vector).
    I'm using c++ types here in the application as they are used by a controller written in pure c++.

    I also suspect that you are using lock in wrong way.
    I originally used a mutex lock but found in the documentation that this is the way to do it, so just copied that method.

    Note that consumer should be faster then producer or event queue of consumer may grow.
    There is sort of a looping of signals and slots between the two threads, one does not emit more signals than it receives from the other, this should stop and event queue growing too much I would think.

  7. #6
    Join Date
    Nov 2010
    Posts
    57
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    4
    Thanked 1 Time in 1 Post

    Default Re: Emitting a signal is corrupting data

    Actually that last statement I made is not true. I emit a lot of signals from my outer thread at the gui thread without requesting them first. Can I track them in the gui thread or just flush them occasionally?

  8. #7
    Join Date
    Nov 2010
    Posts
    57
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanks
    4
    Thanked 1 Time in 1 Post

    Default Re: Emitting a signal is corrupting data

    Hi

    I now emit the data as int and QString from the Gui thread, my slot in the other thread converts the Qt types to c++ types. Now only the outer thread handles the struct creations and deletions. I thought that perhaps there would be less traffic passing a pointer, but if it is unstable then I can't use it.

    This has now run 16 hours without problems.

    Thanks heaps MarekR22!

Similar Threads

  1. Problem emitting a signal
    By franco.amato in forum Qt Programming
    Replies: 1
    Last Post: 16th December 2009, 01:56
  2. Emitting signal from DLL to EXE
    By Miihkali in forum Qt Programming
    Replies: 6
    Last Post: 27th March 2009, 09:32
  3. disconnect SIGNAL/SLOT directly after emitting data
    By donglebob in forum Qt Programming
    Replies: 1
    Last Post: 4th February 2009, 23:53
  4. Replies: 3
    Last Post: 21st December 2008, 13:23
  5. cost of emitting signal
    By quickNitin in forum Newbie
    Replies: 1
    Last Post: 29th November 2006, 09:53

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.