Results 1 to 19 of 19

Thread: Using QUdpSocket within a QThread

  1. #1
    Join Date
    Feb 2007
    Posts
    48
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Using QUdpSocket within a QThread

    Hopefully someone can help with this problem. I have created a QThread to work in conjunction with a GUI app. When runing the executable everything works great. However, after shutting down the application and trying to restart it within 5 seconds or so I get the following error:

    GThread-ERROR **: GThread system may only be initialized once.
    aborting...
    Segmentation fault

    I thought from the way may code was written that everything (includeing the thread) are terminated, but it appears that the thread is still running. How do I get it to stop completely. Using RedHat EL 4


    Thanks for the help.

    Here is my code:
    Qt Code:
    1. // Main -----------------------------------------------------------------
    2.  
    3. int main(int argc, char *argv[])
    4. {
    5. // creates class that contains packets and methods
    6. CHostIFTools * hostifTools = new CHostIFTools();
    7.  
    8. // create threads to handle UDP recieves and tranmits
    9. CHostIF hostifReceive( hostifTools );
    10.  
    11. // start independant threads
    12. hostifReceive.start();
    13.  
    14. // create application class
    15. QApplication app(argc,argv);
    16. CHostIF * hostif = new CHostIF( 0, hostifTools );
    17.  
    18. // display main widget
    19. hostif->show();
    20.  
    21. // run application
    22. app.exec();
    23.  
    24. // stop independant threads
    25. hostifReceive.quit();
    26.  
    27. // wait for thread to finish
    28. hostifReceive.wait();
    29.  
    30. // delay to ensure that threads are really terminated
    31. printf("Waiting for thread to shutdown");
    32. fflush(stdout);
    33.  
    34. for (int sleepIdx=0; sleepIdx<5; sleepIdx++)
    35. {
    36. printf("..");
    37. fflush(stdout);
    38. sleep (1);
    39. }
    40. printf("done!!\n");
    41. fflush(stdout);
    42.  
    43. // need to remove the tools class
    44. delete hostifTools;
    45.  
    46. return 0;
    47. }
    48.  
    49.  
    50. // Class definition ----------------------------------------------------------------------
    51.  
    52. class CHostIFReceive : public QThread
    53. {
    54. public:
    55.  
    56. // CHostIFReceive : class initialization method
    57. CHostIFReceive( CHostIFTools * tools=0 );
    58.  
    59. // ~CHostIFReceive : class destrcutor method
    60. ~CHostIFReceive();
    61.  
    62. // run : local implementation of the QThread run method
    63. void run();
    64.  
    65. // stop : used to set the stop variable
    66. void quit();
    67.  
    68. protected:
    69.  
    70. // defines the tools class that is to be used
    71. CHostIFTools * hostifTools;
    72.  
    73. // provides clean approch to terminting the thread
    74. volatile bool stopThreads;
    75. };
    76.  
    77. // Class code ----------------------------------------------------------------------------
    78.  
    79. CHostIFReceive::CHostIFReceive(CHostIFTools * tools)
    80. : QThread()
    81. {
    82. // instantiate configuration tools class
    83. hostifTools = tools;
    84.  
    85. // indicate thread is in a running state
    86. stopThreads = false;
    87. }
    88.  
    89. void CHostIFReceive::run()
    90. {
    91. // as long as thread has not been terminated
    92. while ( ! stopThreads )
    93. {
    94. // update the system value
    95. hostifTools->updateSystemInformation1();
    96.  
    97. // wait for a little while
    98. sleep( 1 );
    99.  
    100. }
    101. }
    102.  
    103. void CHostIFReceive::quit()
    104. {
    105. stopThreads = true;
    106. QThread::quit();
    107. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by jacek; 29th October 2007 at 22:32. Reason: missing [code] tags

  2. #2
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread - error after stopping

    The first mistake is that you create QObjects(the thread) before you instantiate the QApplication.

    Correct that problem and see if something changes.

    EDIT: and calling QThread::quit has no effect since your implementation does not start and event loop, so you might as well remove that call.

  3. The following user says thank you to marcel for this useful post:

    db (30th October 2007)

  4. #3
    Join Date
    Feb 2007
    Posts
    48
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread - error after stopping

    OK. So I tried your corrections and they worked. So it will now create the thread, now I have one last issue with the code. I have added a UDP socket to it but when is starts up I get the following:

    Object::connect: No such slot QThread::dataPending()

    How do I get it to recognize the dataPending to be associacted with the socket?

    Thanks, you have be a greate help

    Here is an update to my code with the UDP in it.
    Qt Code:
    1. class CHostIFReceive : public QThread
    2. {
    3. public:
    4.  
    5. … same code
    6.  
    7. private slots:
    8. // receives the data from the UDP packet
    9. void dataPending();
    10.  
    11. protected:
    12.  
    13. … same code
    14.  
    15. // declare the UDP socket
    16. QUdpSocket * receiveSocket;
    17.  
    18. // indicates the UDP port that is bound
    19. unsigned int portNumber;
    20.  
    21. };
    22.  
    23. //----------------------------------------------
    24.  
    25. CHostIFReceive::CHostIFReceive(CHostIFTools * tools)
    26. : QThread()
    27. {
    28. … same code
    29.  
    30. // get port number to be used
    31. portNumber = atoi( getenv("HOSTIFPORT") );
    32. qDebug("Port number: %d",portNumber);
    33.  
    34. // create the UDP class for receiving data
    35. receiveSocket = new QUdpSocket( 0 );
    36. receiveSocket->bind( portNumber );
    37.  
    38. connect( receiveSocket, SIGNAL(readyRead()), this, SLOT(dataPending()) );
    39. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by jacek; 29th October 2007 at 22:38. Reason: missing [code] tags

  5. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread - error after stopping

    Quote Originally Posted by db View Post
    Object::connect: No such slot QThread::dataPending()
    Did you remember about Q_OBJECT macro?

    Quote Originally Posted by db View Post
    // create the UDP class for receiving data
    receiveSocket = new QUdpSocket( 0 );
    You shouldn't create any objects in QThread constructor, if you are going to use them in a new thread --- instantiate them in run() instead.

    Quote Originally Posted by db View Post
    connect( receiveSocket, SIGNAL(readyRead()), this, SLOT(dataPending()) );
    You have to use a direct connection here, because "this" lives in the GUI thread and if you use an automatic connection, your slot will be executed by GUI thread. Pass Qt::DirectConnection as the fifth parameter.

  6. #5
    Join Date
    Feb 2007
    Posts
    48
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Using QUdpSocket within a QThread

    I am trying to create a thread class that contains a QUdpSocket object within it. My code builds and executes, but when it starts up I get the following error:

    "Object::connect: No such slot QThread::processPendingDatagrams."

    So obviously the dataReady signal will not get processed. How do I resolve the error??

    I have tried several approaches:

    1) Previously, it was suggested that I may need a Q_OBJECT in the Thread class; I didn’t think so because I’m not using a widget (may be an incorrect assumption on my part). I put it in the code and got linker errors:

    "Undefined reference to vtable for CHostIFReceive."

    My understanding is that it thinks I’m using a virtual object that hasn’t been declared, I didn’t think I was.

    2) Another suggesting was that I should not create the QUpdSocket in the QThread constructor but in the run() method (all the examples I’ve seen have it in the constructor). I got the following runtime errors:

    "QObject can not create children for a parent that is in a different thread.
    (Parent is QThread(0xbfefb140), parent’s thread is QThread(0x9e9c2e8), current thread is QThread(0xbfefb140)
    Object::connect: No such slot QThread::processPendingDatagrams."

    3) Final suggestion was to make sure that I pass in Qt::DirectConnection as the fifth parameter for the connect() method. That had no affect.

    I’m thinking that it should be straight forward soloution but don’t see it. Any other suggestions?

    My code:

    Qt Code:
    1. // Main code ----------------------------------------------------------------------
    2.  
    3. int main(int argc, char *argv[])
    4. {
    5. // create application class
    6. QApplication app(argc,argv);
    7.  
    8. // creates class that contains packets and methods
    9. CHostIFTools * hostifTools = new CHostIFTools();
    10.  
    11. // create threads to handle UDP recieves and tranmits
    12. CHostIF hostifReceive( hostifTools );
    13.  
    14. // start independant threads
    15. hostifReceive.start();
    16.  
    17. // create the application's gui class
    18. CHostIF * hostif = new CHostIF( 0, hostifTools );
    19.  
    20. // display main widget
    21. hostif->show();
    22.  
    23. // run application
    24. app.exec();
    25.  
    26. // stop independant threads
    27. hostifReceive.stop();
    28.  
    29. // wait for thread to finish
    30. hostifReceive.wait();
    31.  
    32. // need to remove the tools class
    33. delete hostifTools;
    34.  
    35. return 0;
    36. }
    37.  
    38.  
    39. // Class definition ----------------------------------------------------------------------
    40.  
    41. class CHostIFReceive : public QThread
    42. {
    43. public:
    44.  
    45. // CHostIFReceive : class initialization method
    46. CHostIFReceive( CHostIFTools * tools=0 );
    47.  
    48. // ~CHostIFReceive : class destrcutor method
    49. ~CHostIFReceive();
    50.  
    51. // run : local implementation of the QThread run method
    52. void run();
    53.  
    54. // stop : used to set the stop variable
    55. void stop();
    56.  
    57. private slots:
    58. // receives the data from the UDP packet
    59. void processPendingDatagrams();
    60.  
    61. protected:
    62.  
    63. // defines the tools class that is to be used
    64. CHostIFTools * hostifTools;
    65.  
    66. // provides clean approch to terminting the thread
    67. volatile bool stopThreads;
    68.  
    69. // declare the UDP socket
    70. QUdpSocket * receiveSocket;
    71.  
    72. // indicates the UDP port that is bound
    73. unsigned int portNumber;
    74. };
    75.  
    76. // Class code ----------------------------------------------------------------------------
    77.  
    78. CHostIFReceive::CHostIFReceive(CHostIFTools * tools)
    79. : QThread()
    80. {
    81. // instantiate configuration tools class
    82. hostifTools = tools;
    83.  
    84. // indicate thread is in a running state
    85. stopThreads = false;
    86.  
    87. // get port number to be used
    88. portNumber = atoi( getenv("HOSTIFPORT") );
    89. qDebug("Port number: %d",portNumber);
    90.  
    91. // create the UDP class for receiving data
    92. receiveSocket = new QUdpSocket( 0 );
    93. receiveSocket->bind( portNumber );
    94.  
    95. connect( receiveSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams()) );
    96. }
    97.  
    98. // -----------
    99.  
    100. CHostIFReceive::~CHostIFReceive() {}
    101.  
    102. // -----------
    103.  
    104. void CHostIFReceive::run()
    105. {
    106. // as long as thread has not been terminated
    107. while ( ! stopThreads )
    108. {
    109. // update the system value
    110. hostifTools->updateSystemInformation1();
    111.  
    112. // wait for a little while
    113. sleep( 1 );
    114.  
    115. }
    116. }
    117.  
    118. // -----------
    119.  
    120. void CHostIFReceive::stop()
    121. {
    122. stopThreads = true;
    123. }
    124.  
    125. // -----------
    126.  
    127. void CHostIFReceive::processPendingDatagrams()
    128. {
    129. ; // nothing for now since error happes before actual processing
    130. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by jacek; 30th October 2007 at 20:41. Reason: missing [code] tags

  7. #6
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Using QUdpSocket within a QThread

    make the slot public
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  8. #7
    Join Date
    Feb 2007
    Posts
    48
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread - error after stopping

    I have tried the different approaches, and none of them solved the problem.

    1) It was suggested that I may need a Q_OBJECT in the Thread class; I didn’t think so because I’m not using a widget (may be an incorrect assumption on my part). I put it in the code and got linker errors:

    "Undefined reference to vtable for CHostIFReceive."

    My understanding is that it thinks I’m using a virtual object that hasn’t been declared, I didn’t think I was.

    2) Another suggesting was that I should not create the QUpdSocket in the QThread constructor but in the run() method (all the examples I’ve seen have it in the constructor). I got the following runtime errors:

    "QObject can not create children for a parent that is in a different thread.
    (Parent is QThread(0xbfefb140), parent’s thread is QThread(0x9e9c2e8), current thread is QThread(0xbfefb140)
    Object::connect: No such slot QThread:rocessPendingDatagrams."

    3) Final suggestion was to make sure that I pass in Qt:irectConnection as the fifth parameter for the connect() method. That had no affect.

  9. #8
    Join Date
    Feb 2007
    Posts
    48
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Using QUdpSocket within a QThread

    I tried the public (and protected) slot approach. Still get the same error.

  10. #9
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Using QUdpSocket within a QThread

    First of all, you're missing the Q_OBJECT macro. Secondly, create the socket in QThread::run(), not in constructor. And finally, make sure you enforce the connection as direct because otherwise the slot will get called in main thread's context (that's where the thread object itself "lives" in):
    Qt Code:
    1. connect( receiveSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams()), Qt::DirectConnection);
    To copy to clipboard, switch view to plain text mode 
    J-P Nurmi

  11. #10
    Join Date
    Feb 2007
    Posts
    48
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Using QUdpSocket within a QThread

    Actually if you read the top portion of my post you would see that I tried all thoses suggestions already and it did not work. In fact I got even more error messages.

    Thanks

  12. #11
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Using QUdpSocket within a QThread

    Quote Originally Posted by db View Post
    1) Previously, it was suggested that I may need a Q_OBJECT in the Thread class; I didn’t think so because I’m not using a widget (may be an incorrect assumption on my part). I put it in the code and got linker errors:

    "Undefined reference to vtable for CHostIFReceive."

    My understanding is that it thinks I’m using a virtual object that hasn’t been declared, I didn’t think I was.
    Make sure the declaration is in a header file and that the header file is listed in .pro file. Then, re-run qmake to get new Makefiles with correct rules for running moc as required.

    2) Another suggesting was that I should not create the QUpdSocket in the QThread constructor but in the run() method (all the examples I’ve seen have it in the constructor). I got the following runtime errors:

    "QObject can not create children for a parent that is in a different thread.
    (Parent is QThread(0xbfefb140), parent’s thread is QThread(0x9e9c2e8), current thread is QThread(0xbfefb140)
    Object::connect: No such slot QThread:rocessPendingDatagrams."
    Yes, QThread::run() is the correct place to create it. Just don't pass any parent. Again, the QThread object itself aka "this" lives in main thread which is different thread which is being executed in QThread::run().

    3) Final suggestion was to make sure that I pass in Qt:irectConnection as the fifth parameter for the connect() method. That had no affect.
    Yes, you'll need to pass it. See the explanation in my previous post.
    J-P Nurmi

  13. #12
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread - error after stopping

    It was suggested that I may need a Q_OBJECT in the Thread class; I didn’t think so because I’m not using a widget (may be an incorrect assumption on my part). I put it in the code and got linker errors:
    Not only QWidget sibclasses but all classes that use/implement signals and slots have to have the Q_OBJECT macro in order to be processed by moc. So, it is mandatory in your case.

    "Undefined reference to vtable for CHostIFReceive."

    My understanding is that it thinks I’m using a virtual object that hasn’t been declared, I didn’t think I was.
    Do you implement two classes in the same cpp? There was a similar problem on the forum, still unsolved unfortunately. Try splitting the declarations and implementations for classes containing the Q_OBJECT macro.

    2) Another suggesting was that I should not create the QUpdSocket in the QThread constructor but in the run() method (all the examples I’ve seen have it in the constructor). I got the following runtime errors:

    "QObject can not create children for a parent that is in a different thread.
    (Parent is QThread(0xbfefb140), parent’s thread is QThread(0x9e9c2e8), current thread is QThread(0xbfefb140)
    Object::connect: No such slot QThread:rocessPendingDatagrams."
    You'll have to post the thread code for this. Probably something got mixed up.
    It might be that the worker thread object lives in the GUI thread. If you move it to itself after it is started could solve the problem.

    Final suggestion was to make sure that I pass in Qt:irectConnection as the fifth parameter for the connect() method. That had no affect.
    If the socket lives in the worker thread there will be no need to specify the connection type. It will default to direct.

    Also, make sure you start the event loop in the thread with exec, otherwise thread slots won't work.

  14. #13
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread - error after stopping

    Quote Originally Posted by db View Post
    "QObject can not create children for a parent that is in a different thread.
    (Parent is QThread(0xbfefb140), parent’s thread is QThread(0x9e9c2e8), current thread is QThread(0xbfefb140)
    You shouldn't create the socket with a parent --- create it just like in the code you have posted earlier, but in run().

    Quote Originally Posted by db View Post
    Final suggestion was to make sure that I pass in Qt:irectConnection as the fifth parameter for the connect() method. That had no affect.
    If you stay with automatic connections, don't be surprised when you discover that the GUI thread does all of the work.

  15. #14
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread - error after stopping

    Quote Originally Posted by marcel View Post
    If the socket lives in the worker thread there will be no need to specify the connection type. It will default to direct.
    On the contrary. The receiver, i.e. QThread, lives in the GUI thread and the socket lives in the worker thread, so the connection will be queued and all signals will land in GUI thread's event queue.

  16. #15
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Using QUdpSocket within a QThread

    Please, don't start more than one thread on the same problem.

    {Threads merged}
    Last edited by jacek; 30th October 2007 at 20:42.

  17. #16
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread - error after stopping

    Yes but you can always move the QThread object from to GUI thread to the worker thread to solve this. This way connect will default to Qt:irectConnection and the slot gets executed by the worker thread.

    Or, as you said, can leave it like it already is and force a direct connection.
    EDIT: both approaches work, but I prefer the one with changing the object's affinity. Don't really know why, though...

  18. #17
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QThread - error after stopping

    Quote Originally Posted by marcel View Post
    Yes but you can always move the QThread object from to GUI thread to the worker thread to solve this. This way connect will default to Qt::DirectConnection and the slot gets executed by the worker thread.
    Of course, but won't that create problems after the thread stops? You will end with an object that lives in a non-existent thread.

  19. #18
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Using QUdpSocket within a QThread

    You're right! Never thought of that.
    I wonder if there's a solution for this. Maybe the finished() signal can be used to delete the QThread object.
    Indeed, changing affinities sucks.

  20. #19
    Join Date
    Feb 2007
    Posts
    48
    Thanks
    6
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Using QUdpSocket within a QThread

    JPN, Thanks for walking me through the change with explanations... I did miss the qmake and of course removing the parent in the instaniation help also.

    Marcel, Jacek, Thanks for your inputs also. I got lost in some of the stuff but being a newbie I'm sure it will eventually make sense.

    also my bad about the 2 threads but I thought that I was starting a new topic with the QUdpSocket so...

    Again, thanks guys

Similar Threads

  1. Problem with QTcpSocket in QThread
    By Raistlin in forum Qt Programming
    Replies: 8
    Last Post: 6th October 2007, 12:23
  2. QThread exec proplem to stop...
    By patrik08 in forum Qt Programming
    Replies: 29
    Last Post: 21st May 2007, 07:51
  3. Qthread Issue?
    By vishal.chauhan in forum Newbie
    Replies: 3
    Last Post: 29th March 2007, 08:50
  4. how to use QHttp inside QThread in Qt3
    By alusuel in forum Qt Programming
    Replies: 3
    Last Post: 14th July 2006, 11:19
  5. Is it possible to create a QThread without inheriting ?
    By probine in forum Qt Programming
    Replies: 6
    Last Post: 23rd March 2006, 22:51

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.