Results 1 to 2 of 2

Thread: Problem in synchronization between QThreads

  1. #1
    Join Date
    Oct 2013
    Location
    Everett WA USA
    Posts
    12
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11

    Default Problem in synchronization between QThreads

    Dear Experts,

    I am working on an application which will exchange the data between the Qt thread and the windows console application. I am developing these applications using MS VS 2008 with Qt plugin in Windows platform.

    The design is as follows:

    • Windows "NamedPipe" is used as IPC for exchaning the data between two applications.
    • AplicationA
      • Main GUI application designed using Qt and it has two dedicated QThreads for read and write operations on NamedPipe.
      • Creates Windows "NamedPipe" in on startup using
        Qt Code:
        1. m_shPipeHandle = CreateNamedPipe(
        2. lpszPipename, // pipe name
        3. PIPE_ACCESS_DUPLEX, // read/write access
        4. PIPE_TYPE_MESSAGE | // message type pipe
        5. PIPE_READMODE_MESSAGE | // message-read mode
        6. PIPE_WAIT, // blocking mode
        7. PIPE_UNLIMITED_INSTANCES, // max. instances
        8. BUFFER_SIZE, // output buffer size
        9. BUFFER_SIZE, // input buffer size
        10. NMPWAIT_USE_DEFAULT_WAIT, // client time-out
        11. NULL); // default security attribute
        To copy to clipboard, switch view to plain text mode 
      • Launches "ApplicationB" using
        Qt Code:
        1. QProcess::startDetached("ApplicationB.exe");
        To copy to clipboard, switch view to plain text mode 
      • Starts two Qt Threads (one for read operation and another for write operation) using
        Qt Code:
        1. m_pReaderThread = new QThread;
        2. m_pReader = new CWorker();
        3. m_pWriterThread = new QThread;
        4. m_pWriter = new CWorker();
        5.  
        6. m_pReader->moveToThread(m_pReaderThread);
        7. m_pWriter->moveToThread(m_pWriterThread);
        8.  
        9. connect(m_pReaderThread, SIGNAL(started()), m_pReader, SLOT(doReadData()));
        10. connect(m_pReader, SIGNAL(finishedWork()), m_pReaderThread, SLOT(quit()));
        11. connect(m_pReader, SIGNAL(finishedWork()), m_pReader, SLOT(deleteLater()));
        12. connect(m_pReaderThread, SIGNAL(finished()), m_pReaderThread, SLOT(deleteLater()));
        13.  
        14. connect(m_pWriterThread, SIGNAL(started()), m_pWriter, SLOT(doWriteData()));
        15. connect(m_pWriter, SIGNAL(finishedWork()), m_pWriterThread, SLOT(quit()));
        16. connect(m_pWriter, SIGNAL(finishedWork()), m_pWriter, SLOT(deleteLater()));
        17. connect(m_pWriterThread, SIGNAL(finished()), m_pWriterThread, SLOT(deleteLater()));
        18.  
        19. connect(m_pSampleUi->btnStartStop, SIGNAL(clicked()), this, SLOT(sltToggleButton()));
        20.  
        21. m_pReaderThread->start();
        22. m_pWriterThread->start();
        To copy to clipboard, switch view to plain text mode 

        The `CWorker::doReadData()` looks as follows:
        Qt Code:
        1. void CWorker::doReadData()
        2. {
        3. char szBuffer[BUFFER_SIZE];
        4. DWORD cbBytes;
        5. bool bResult = false;
        6.  
        7. ConnectNamedPipe(CWorker::m_shPipeHandle, NULL);
        8.  
        9. do {
        10. //Read client message
        11. bResult = ReadFile(
        12. m_shPipeHandle, // handle to pipe
        13. szBuffer, // buffer to receive data
        14. BUFFER_SIZE, // size of buffer
        15. &cbBytes, // number of bytes read
        16. NULL); // not overlapped I/O
        17.  
        18. if ((!bResult) || (!cbBytes))
        19. {
        20. qDebug()<<"\nError occurred while reading from the client:"<<GetLastError();
        21. // TODO: Action to be taken on failure
        22. }
        23. else
        24. {
        25. qDebug()<<"Client sent following message:"<<szBuffer;
        26. // Inform the Main UI thread to update UI elements or to do necessary action.
        27. emit dataAvailable(QString(szBuffer).toInt());
        28.  
        29. // Update the shared m_enumCmd so that Writer thread can write the Acknowledgement in NamedPipe so that "ApplicationB" can read & process it.
        30. m_Mutex.lock();
        31. m_enumCmd = COMMAND_ACK_READ;
        32. m_Mutex.unlock();
        33.  
        34. // Release the semaphore so that writer thread can acquire and starts writing the data (ACK) onto the pipe.
        35. m_Sem.release();
        36. }
        37. } while(m_bReadThreadControl);
        38. }
        To copy to clipboard, switch view to plain text mode 

        The `CWorker::doWriteData()` looks as follows:
        Qt Code:
        1. void CWorker::doWriteData()
        2. {
        3. DWORD cbBytes;
        4. bool bResult = false;
        5. char szBuffer[BUFFER_SIZE];
        6.  
        7. do
        8. {
        9. m_Sem.acquire();
        10.  
        11. qDebug()<<"\nInside the Write Loop\n";
        12.  
        13. switch(m_enumCmd)
        14. {
        15. case COMMAND_PAUSE_SERVICE:
        16. sprintf(szBuffer, "%d", COMMAND_PAUSE_SERVICE);
        17. break;
        18. case COMMAND_RESUME_SERVICE:
        19. sprintf(szBuffer, "%d", COMMAND_RESUME_SERVICE);
        20. break;
        21. case COMMAND_ACK_READ:
        22. sprintf(szBuffer, "%d", COMMAND_ACK_READ);
        23. break;
        24. case COMMAND_UNKNOWN:
        25. default:
        26. szBuffer[0] = '\0';
        27. break;
        28. }
        29.  
        30. bResult = WriteFile(
        31. m_shPipeHandle, // handle to pipe
        32. szBuffer, // buffer to write from
        33. strlen(szBuffer) + 1, // number of bytes to write, include the NULL
        34. &cbBytes, // number of bytes written
        35. NULL);
        36.  
        37. if ((!bResult) || (!cbBytes))
        38. {
        39. qDebug()<<"\nError occurred while writing to the client:"<<GetLastError();
        40. // TODO: Action to be taken on failure
        41. }
        42. else
        43. {
        44. qDebug()<<"Written data is: "<<szBuffer;
        45. }
        46.  
        47. } while (m_bWriteThreadControl);
        48. }
        To copy to clipboard, switch view to plain text mode 






    • ApplicationB
      • Its normal windows console application.
      • Connects to the named pipe using
        Qt Code:
        1. //Connect to the server pipe using CreateFile()
        2. hPipe = CreateFile(
        3. lpszPipename, // pipe name
        4. GENERIC_READ | GENERIC_WRITE, // read and write access
        5. 0, // no sharing
        6. NULL, // default security attributes
        7. OPEN_EXISTING, // opens existing pipe
        8. FILE_ATTRIBUTE_NORMAL, // default attributes
        9. NULL); // no template file
        To copy to clipboard, switch view to plain text mode 
      • Waits for input from user and writes the user data to the Pipe and then it waits for the acknowledgement from the server.
        Qt Code:
        1. while (1)
        2. {
        3. // Reset the buffer
        4. szBuffer[0] = 0;
        5.  
        6. // Wait for the user input and update msgId;
        7.  
        8. // Store the msg id value to the szBuffer.
        9. sprintf(szBuffer, "%d", msgId);
        10. szBuffer[strlen(szBuffer)] = 0;
        11.  
        12. //Send the message to server
        13. BOOL bResult = WriteFile(
        14. hPipe, // handle to pipe
        15. szBuffer, // buffer to write from
        16. strlen(szBuffer) + 1, // number of bytes to write, include the NULL
        17. &cbBytes, // number of bytes written
        18. NULL); // not overlapped I/O
        19.  
        20. if ((!bResult) || (!cbBytes))
        21. {
        22. std::cout<<"\nError occurred while writing to the server:"<<GetLastError();
        23. }
        24. else
        25. {
        26. std::cout<<"\nWriteFile() was successful.";
        27. std::cout<<"\nWritten"<<szBuffer<<"to the Pipe\n";
        28. }
        29.  
        30. //Read server response
        31. bResult = ReadFile(
        32. hPipe, // handle to pipe
        33. szBuffer, // buffer to receive data
        34. BUFFER_SIZE,
        35. &cbBytes, // number of bytes read
        36. NULL); // not overlapped I/O
        37.  
        38. if ((!bResult) )//|| (0 == cbBytes))
        39. {
        40. std::cout<<"\nError occurred while reading from the server:"<<GetLastError();
        41. }
        42. else
        43. {
        44. std::cout<<"\nReadFile() was successful.";
        45. std::cout<<"\nServer sent the following message:"<<szBuffer<<std::endl;
        46. }
        47. }
        To copy to clipboard, switch view to plain text mode 

    Questions:
    My intention is to dedicate a thread exclusively for Read operation and another thread exclusively for Write operation. Even if the ReadThread wants to send any data (say acknowledgement) it should intimate the WriterThread (by releasing semaphore).
    • a. Is there anything wrong in the way I am trying to synchronize the read and write operations at the Qt Application side.
    • b. Will there be any problem If we try to synchronze the operations between the the QProcess (Console App) and the QThreads?
    • c. How do I synchronize the read/write operations without any delay between Qt Application and Console Application.
    • d. Can you please suggest the better way to achieve this functionality

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Problem in synchronization between QThreads

    Cannot you just use QLocalSocket?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. QItemSelectionModel synchronization problem - SOLVED
    By d_stranz in forum Qt Programming
    Replies: 0
    Last Post: 16th May 2014, 19:06
  2. thread synchronization
    By freekill in forum Qt Programming
    Replies: 10
    Last Post: 6th January 2010, 17:29
  3. Thread Synchronization Problem
    By sijithjames in forum Qt Programming
    Replies: 13
    Last Post: 13th November 2009, 14:53
  4. audi/video synchronization problem in qtopia
    By Savita in forum Qt for Embedded and Mobile
    Replies: 0
    Last Post: 19th February 2008, 06:10
  5. QSplitter synchronization
    By sreedhar in forum Qt Programming
    Replies: 2
    Last Post: 11th July 2006, 17:22

Tags for this Thread

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.