Results 1 to 4 of 4

Thread: The relationship between QT UI and custom thread using 'pthread' in QT Application.

  1. #1
    Join Date
    Feb 2019
    Posts
    6
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default The relationship between QT UI and custom thread using 'pthread' in QT Application.

    Hi all,

    I am going to ask about one strange issue.
    I hope you understand that my English skills are poor.

    I have a embedded(arm, linux) device and there is running a QT(4.7) Application.

    QT Application consist of "many Widgets" (QPushButtons, QLabels, etc...) and "a custom thread" (pthread).
    The role of the "custom thread" is to communicate with other devices.
    The role of the "many Widgets" is to setText the data from the "custom thread" by pressing some button('A' Button) and display the fixed text by pressing another button('B' Button).

    The issue is that the data received in the "custom thread" is not updated(call with "setText"), or the program is killed ("Segment fault").

    Looking at the pseudocode will make it easier to understand.

    Qt Code:
    1. QPushButton * buttonA;
    2. QPushButton * buttonB;
    3. QLabel * label;
    4.  
    5. pthread_mutex_t threadMutex;
    6. pthread_cond_t threadCond;
    7. pthread_t thread;
    8.  
    9. int recvBuffer;
    10.  
    11. static void * network_loop( void * parg )
    12. {
    13. int socketFd = -1;
    14. socketFd = socket( "Network Socket open" );
    15.  
    16. struct sockaddr_in addr;
    17. addr.sin_family = AF_INET;
    18. addr.sin_addr.s_addr = inet_addr("Server IP address");
    19. addr.sin_port = htons(Server_Listen_Port);
    20.  
    21. connect( socketFd, (struct socketaddr*)&addr, sizeof(addr) );
    22.  
    23. while( 1 ) {
    24. pthread_mutex_lock( &threadMutex );
    25. while( isThreadRunning == true ) {
    26. send( socketFd, "request data", strLength, MSG_NOSIGNAL );
    27. recv( socketFd, (void *)&recvBuffer, BUFFER_SIZE, 0 );
    28. test_widget* mTestWidget = (test_widget*)parg;
    29. mTestWidget->update_text( );
    30. }
    31. pthread_mutex_unlock( &threadMutex );
    32.  
    33. pthread_mutex_lock( &threadMutex );
    34. if( isThreadRunning == false )
    35. pthread_cond_wait( &threadCond, &threadMutex );
    36. pthread_mutex_unlock( &threadMutex );
    37. }
    38. }
    39.  
    40. void test_widget::update_text( )
    41. {
    42. label->setText( QString::number(recvBuffer) );
    43. }
    44.  
    45. test_widget::test_widget( QWidget * parent ) : QWidget(parent)
    46. {
    47. isThreadRunning = false;
    48.  
    49. pthread_mutex_init( &threadMutex, NULL );
    50. pthread_cond_init( &threadCond, NULL );
    51. pthread_create( &thread, NULL, network_loop, (void *)this );
    52.  
    53. buttonA = new QPushButton( parent );
    54. buttonB = new QPushButton( parent );
    55. label = new QLabel( parent );
    56.  
    57. buttonA->setGeometry( 0, 0, 10, 10 );
    58. buttonB->setGeometry( 20, 0, 10, 10 );
    59. label->setGeometry( 0, 40, 20, 10 );
    60. label->setText( "default" );
    61.  
    62. connect( buttonA, SIGNAL(clicked()), this, SLOT(buttonA_click()) );
    63. connect( buttonB, SIGNAL(clicked()), this, SLOT(buttonB_click()) );
    64. }
    65.  
    66. void test_widget::buttonA_click( )
    67. {
    68. isThreadRunning = true;
    69. pthread_cond_signal( &threadCond );
    70. }
    71.  
    72. void test_widget::buttonB_click( )
    73. {
    74. isThreadRunning = false;
    75. label->setText( "good" );
    76. }
    To copy to clipboard, switch view to plain text mode 

    This codes tells three things.
    1. buttonA push : thread executes. And label->setText calls with received data.
    2. buttonB push : thread stops. And label->setText calls with "good"
    3. if thread executes, it calls the member function of "test_widget".

    There is no problem when starting QT Application. But when I press button 'A' and 'B' alternately, when the button 'A' is pressed at some point, the number is not updated. Then sometimes the program is killed.(Segment fault)
    (The above code is a pseudocode, so it may not work. If you want the code for testing, I can provide it.)

    I want to know the cause of this issue. Please help me.
    Thanks.

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,251
    Thanks
    36
    Thanked 1,508 Times in 1,459 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: The relationship between QT UI and custom thread using 'pthread' in QT Applicatio

    Rule number 1 when working with threads in Qt: never ever access a widget in a secondary thread.

    You can
    1) Send an event to the main thread
    2) Call a widget slot via QMetaObject::invokeMethod3) Emit a signal and use a cross-thread signal slot connection.

    Any specific reason why you are using low-level, system specific, threading API and not simply QThread?

    Cheers,
    _

  3. #3
    Join Date
    Feb 2019
    Posts
    6
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: The relationship between QT UI and custom thread using 'pthread' in QT Applicatio

    Thank you very much your reply !! :-)

    "Rule number 1 when working with threads in Qt: never ever access a widget in a secondary thread."
    ==> I'm just curious, is there a reason for that??


    "1) Send an event to the main thread
    2) Call a widget slot via QMetaObject::invokeMethod
    3) Emit a signal and use a cross-thread signal slot connection."
    ==> very good. However, I think I should study QMetaObject. In fact, I do not understand the QMetaObject documentation. (https://doc.qt.io/archives/qt-4.8/qm...l#invokeMethod) :-(


    "Any specific reason why you are using low-level, system specific, threading API and not simply QThread?"
    ==> I could use QThread. But, can not use QThread proficiently and there are API functions provided by the embedded device.


    Thank you Anda_skoa.

  4. #4
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,251
    Thanks
    36
    Thanked 1,508 Times in 1,459 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: The relationship between QT UI and custom thread using 'pthread' in QT Applicatio

    Quote Originally Posted by jslim View Post
    "Rule number 1 when working with threads in Qt: never ever access a widget in a secondary thread."
    ==> I'm just curious, is there a reason for that??
    Most UI is handled by a single thread, so adding multithread capability, e.g. locking in every widget method, would create lots of overhead for the standard use case.

    And Qt makes it very easy to transfer data from a secondary thread to the main thread, so even the MT case is not complicated for the application developer either.

    Quote Originally Posted by jslim View Post
    "1) Send an event to the main thread
    2) Call a widget slot via QMetaObject::invokeMethod
    3) Emit a signal and use a cross-thread signal slot connection."
    ==> very good. However, I think I should study QMetaObject. In fact, I do not understand the QMetaObject documentation. (https://doc.qt.io/archives/qt-4.8/qm...l#invokeMethod) :-(
    It basically works like this

    Qt Code:
    1. // Calling a slot without arguments
    2. QMetaObject::invokeMethod(myWidgetPointer, "nameOfSlot", Qt::QueuedConnection);
    3.  
    4. // Calling a slot with arguments
    5. QMetaObject::invokeMethod(myWidgetPointer, "nameOfSlot", Qt::QueuedConnection, Q_ARG(QString, "someString"), Q_ARG(int, 42));
    To copy to clipboard, switch view to plain text mode 
    The QueuedConnection ensures that the slot is called by the thread running the event processing for myWidgetPointer, i.e. the main thread.

    Quote Originally Posted by jslim View Post
    "Any specific reason why you are using low-level, system specific, threading API and not simply QThread?"
    ==> I could use QThread. But, can not use QThread proficiently and there are API functions provided by the embedded device.
    The Qt API is far easier to use and in this case has the nice side effect that you can simply emit a signal from within the thread's loop

    Qt Code:
    1. class MyThread : public QThread
    2. {
    3. Q_OBJECT
    4. protected:
    5. void run() override;
    6.  
    7. signals:
    8. void updateWidgets();
    9. };
    10.  
    11. void MyThread::run()
    12. {
    13. int socketFd = -1;
    14. socketFd = socket( "Network Socket open" );
    15.  
    16. struct sockaddr_in addr;
    17. addr.sin_family = AF_INET;
    18. addr.sin_addr.s_addr = inet_addr("Server IP address");
    19. addr.sin_port = htons(Server_Listen_Port);
    20.  
    21. connect( socketFd, (struct socketaddr*)&addr, sizeof(addr) );
    22.  
    23. while( 1 ) {
    24. pthread_mutex_lock( &threadMutex );
    25. while( isThreadRunning == true ) {
    26. send( socketFd, "request data", strLength, MSG_NOSIGNAL );
    27. recv( socketFd, (void *)&recvBuffer, BUFFER_SIZE, 0 );
    28.  
    29. emit updateWidgets();
    30. }
    31. pthread_mutex_unlock( &threadMutex );
    32.  
    33. pthread_mutex_lock( &threadMutex );
    34. if( isThreadRunning == false )
    35. pthread_cond_wait( &threadCond, &threadMutex );
    36. pthread_mutex_unlock( &threadMutex );
    37. }
    38. }
    To copy to clipboard, switch view to plain text mode 

    Obviously you wouldn't even need a thread for this kind of workload because the Qt socket API can do non-blocking/asynchronous data transfer all by itself

    Cheers,
    _

Similar Threads

  1. Integrating Pthread Library with QT
    By bandarus in forum Newbie
    Replies: 2
    Last Post: 30th January 2017, 09:38
  2. problem in using pthread in QT
    By rinku in forum Newbie
    Replies: 4
    Last Post: 27th September 2012, 13:07
  3. Qthread faster than pthread???
    By lsantos in forum Qt Programming
    Replies: 1
    Last Post: 16th April 2012, 21:58
  4. -pthread havoc
    By Cruz in forum Qt Programming
    Replies: 8
    Last Post: 10th March 2010, 12:22
  5. pthread instead QThread
    By brevleq in forum Qt Programming
    Replies: 8
    Last Post: 23rd December 2008, 07:16

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.