Results 1 to 3 of 3

Thread: Slot priority in multithread

  1. #1
    Join Date
    Apr 2017
    Posts
    30
    Thanks
    9
    Qt products
    Qt5
    Platforms
    Windows

    Default Slot priority in multithread

    Hi all!

    Small fragment of the project:

    mainwindow.cpp
    Qt Code:
    1. //constructor
    2. QThread *thread = new QThread;
    3. //thread = new QThread(this);
    4. valve = new Valve(7);
    5. pressureSensors = new PressureSensors;
    6. valve->moveToThread(thread);
    7. pressureSensors->moveToThread(thread);
    8. connect(pressureSensors, SIGNAL(remoteSignal(bool)), this, SLOT(readPressureSensors(bool)));
    9. connect(valve, SIGNAL(remoteSignal(bool)), this, SLOT(updateStates(bool)));
    10. connect(this, SIGNAL(valveOpen(int)), valve, SLOT(open(int)));
    11. connect(this, SIGNAL(valveClose(int)), valve, SLOT(close(int)));
    12. connect(valve, SIGNAL(valveStatus(int,bool,bool)), this, SLOT(valveIndicate(int,bool,bool)));
    13. QTimer *sensorsReadTimer = new QTimer(this);
    14. sensorsReadTimer->moveToThread(thread);
    15. connect(sensorsReadTimer, SIGNAL(timeout()), pressureSensors, SLOT(readSensors()));
    16. sensorsReadTimer->start(100);
    17. QTimer *valvesReadTimer = new QTimer(this);
    18. valvesReadTimer->moveToThread(thread);
    19. connect(valvesReadTimer, SIGNAL(timeout()), valve, SLOT(getAllStates()));
    20. valvesReadTimer->start(100);
    21. thread->start();
    22. //***//
    23. void MainWindow::openValve(int id)
    24. {
    25. valveButton[id]->setEnabled(false);
    26. //valve->open(id);
    27. emit valveOpen(id);
    28. }
    To copy to clipboard, switch view to plain text mode 

    protocol.cpp
    Qt Code:
    1. bool Valve::open(int id)
    2. {
    3. arr.resize(7);
    4. arr[0] = 0xAB;
    5. arr[1] = 0x01;
    6. arr[2] = 0x02;
    7. arr[3] = 0x02;
    8. arr[4] = id + 1;
    9. arr[5] = 0xFF;
    10. arr[6] = 0x00 - arr[1] - arr[2] - arr[3] - arr[4] - arr[5];
    11.  
    12. QByteArray response = ComPort::get().requestResponse(arr);
    13. if(response[0] == arr[0])
    14. {
    15. qDebug() << "клапан №: " << id << " открыт!";
    16. valveState[id] = true;
    17. emit valveStatus(id, 1, 1);
    18. return 1;
    19. }
    20. emit valveStatus(id, 1, 0);
    21. return 0;
    22. }
    23. bool Valve::getAllStates()
    24. {
    25. arr.resize(5);
    26. arr[0] = 0xAB;
    27. arr[1] = 0x01;
    28. arr[2] = 0x00;
    29. arr[3] = 0x00;
    30. arr[4] = 0x00 - arr[1] - arr[2] - arr[3];
    31.  
    32. QByteArray response = ComPort::get().requestResponse(arr);
    33. if(response[0] == arr[0])
    34. {
    35. QBitArray bitStates(16);
    36.  
    37. for (int i = 4; i<6; i++)
    38. for (int b = 0; b<8; b++)
    39. bitStates.setBit((i-4)*8+b, response.at(i)&(1<<b));
    40. for (int i = 0; i < valveState.size(); i++)
    41. valveState[i] = bitStates[i];
    42. for (uint i = 0; i < sizeof(fittingState); i++)
    43. fittingState[i] = bitStates[i+8];
    44. emit remoteSignal(1);
    45. return 1;
    46. }
    47. emit remoteSignal(0);
    48. return 0;
    49. }
    50. //***//
    51. QByteArray ComPort::requestResponse(const QByteArray &data)
    52. {
    53. mutex->lock();
    54. QByteArray readBuf;
    55. qDebug() << "-------------------------";
    56. if(!serial->isOpen())
    57. open();
    58. int attempts = 1;
    59. while (attempts <= REQATTEMPTS) { //3 попытки
    60. if (serial->isWritable())
    61. {
    62. serial->write(data);
    63. qDebug() << "Попытка № " << attempts;
    64. qDebug() << "Запрос: " << data.toHex();
    65. while (serial->waitForReadyRead(WAITFORREADY)) {
    66. readBuf += serial->readAll();
    67. if (crcCheck(readBuf) && data[2] == readBuf[2] ){ //если CRC и команда сошлись -- успех!
    68. qDebug() << "Ответ: " << readBuf.toHex();
    69.  
    70. responseCount++;
    71. qDebug() << "Кол-во запросов: " << responseCount;
    72. qDebug() << "Кол-во таймаутов: " << timeoutCount;
    73. float percent = timeoutCount * 100;
    74. percent = percent / responseCount;
    75. qDebug() << "Процент косяков: " << QString::number(percent, 'f', 3) << "%";
    76.  
    77. close();
    78. mutex->unlock();
    79. return readBuf;
    80. }
    81. }
    82. //qDebug() << readBuf.toHex();
    83. readBuf.clear();
    84. qDebug() << "Таймаут...";
    85.  
    86. timeoutCount++;
    87.  
    88. close();
    89. open();
    90. attempts++;
    91. }
    92. else
    93. {
    94. qDebug() << "Порт " << portName << " не пишется!";
    95. close();
    96. mutex->unlock();
    97. return 0;
    98. }
    99.  
    100. }
    101. close();
    102. mutex->unlock();
    103. return 0;
    104. }
    To copy to clipboard, switch view to plain text mode 

    If I do not put valve and pressureSensors in a separate thread, then everything works more or less normally.
    But if I put them in a separate thread, the valve opening slot works very late (~ 10 seconds, as lucky). As I understand it, this is because the signal is emitted from the main thread, and the slot is in the other thread. Is it possible to build a queue?

    Slot open from Valve class must have the highest priority.

    Thankful in advance for the help!
    Last edited by maratk1n; 11th May 2017 at 16:50.

  2. #2
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 453 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: Slot priority in multithread

    There are 2 problems in the code
    1. QTimers are created with a parent. Objects with a parent cannot be moved to a thread
    Fix: Create QTimer without parent

    2. QTimer is started after moving to thread. You cannot and should not start a timer which is in another thread.
    Fix: Start the timer before moving to the thread.

    Qt Code:
    1. ...
    2. QTimer *sensorsReadTimer = new QTimer(this); // <<<<<<<<<< Change to new QTimer();
    3. sensorsReadTimer->moveToThread(thread);
    4. connect(sensorsReadTimer, SIGNAL(timeout()), pressureSensors, SLOT(readSensors()));
    5. sensorsReadTimer->start(100); // <<<<<<<<<< Start the timer before moving to the thread
    6. QTimer *valvesReadTimer = new QTimer(this); // <<<<<<<<<< Change to new QTimer();
    7. valvesReadTimer->moveToThread(thread);
    8. connect(valvesReadTimer, SIGNAL(timeout()), valve, SLOT(getAllStates()));
    9. valvesReadTimer->start(100); // <<<<<<<<<< Start the timer before moving to the thread
    10. ...
    To copy to clipboard, switch view to plain text mode 
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

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

    maratk1n (12th May 2017)

  4. #3
    Join Date
    Apr 2017
    Posts
    30
    Thanks
    9
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Slot priority in multithread

    Quote Originally Posted by Santosh Reddy View Post
    There are 2 problems in the code
    1. QTimers are created with a parent. Objects with a parent cannot be moved to a thread
    Fix: Create QTimer without parent

    2. QTimer is started after moving to thread. You cannot and should not start a timer which is in another thread.
    Fix: Start the timer before moving to the thread.
    Thank you very much! This, it seems, helped to solve the problem.

Similar Threads

  1. Setting event priority in QT
    By sanujas in forum Qt for Embedded and Mobile
    Replies: 3
    Last Post: 28th November 2013, 12:37
  2. QUdpSocket and priority
    By Pavlya in forum Qt Programming
    Replies: 5
    Last Post: 11th April 2013, 07:32
  3. Qt thread priority
    By SailinShoes in forum Qt Programming
    Replies: 1
    Last Post: 16th June 2010, 01:39
  4. Error--High Priority
    By sujan.dasmahapatra in forum Qt Programming
    Replies: 2
    Last Post: 5th February 2009, 16:14
  5. priority of QThread
    By quickNitin in forum Qt Programming
    Replies: 3
    Last Post: 13th May 2006, 12: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.