Results 1 to 16 of 16

Thread: No context switch between Threads and parent ?

  1. #1
    Join Date
    Jul 2008
    Posts
    66
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default No context switch between Threads and parent ?

    Hi,

    The following situation is given:

    There is an Object Instance of a Serial Class , which has the abilitiy to read() and write() on com-port. The Serial Class itself has in its privates an instance of a communication library I use.
    The read() write() methods above use methods of this com. library.

    Qt Code:
    1. class Serial:
    2.  
    3. Serial()
    4. {
    5. ...
    6. reader = new threads(this,true);
    7. writer = new threads(this,false);
    8.  
    9. reader->start();
    10. writer->start();
    11. ...
    12. }
    13.  
    14. read()
    15. {
    16. //use here the com library function and some winapi functions to read from the com port
    17. }
    18.  
    19. write()
    20. {
    21. // same as above but or writing
    22. }
    23.  
    24. private:
    25. Seriallibrary Slib; // instance of foreign serial library
    26. Thread-Class *reader,*writer;
    To copy to clipboard, switch view to plain text mode 

    What I wanted to do is following:
    Create two threads, one for reading operations and one for writing operations. (asynchron communication)
    They had to use the methods I provide with my Serial Class.

    What I have done is:

    I created a "Thread-Class" derived from QThread.
    I put two pointers of Type "Thread-Class" to my Serial Class (private member).
    The Ctor of the "Thread-Class" has a boolean, to decide if it is a reader or a writer thread.
    In dependency of that boolean one of two possible loops will be started.

    These two loops use the Serial Class functions provided for writing or reading (with pointer serialPTR).
    I think the whole stuff I designed is wrong. Is every function call I make from the threads running in the context of my Serial Class-Instance ????

    Qt Code:
    1. Threads:
    2.  
    3. Threads(parent *p,bool typeofThread)
    4. {
    5. //take the parent pointer (serialPTR), because I need it to call the provided functions for reading and writing
    6.  
    7. //set a local flag if I am a Reader Thread or a Writer Thread.
    8. }
    9.  
    10.  
    11. run()
    12. {
    13. if(readerFlagIsSet)
    14. while(!threadDone)
    15. {
    16. serialPTR->read();
    17. }
    18.  
    19. if(writerFlagIsSet)
    20. while(!threadDone)
    21. {
    22. serialPTR->write();
    23. }
    24.  
    25. }
    26. // I mean the two function calls above from the thread to the serial-Class
    To copy to clipboard, switch view to plain text mode 

    Can you give me a hint to make that better?
    Or is this way ok?
    Last edited by donglebob; 24th October 2008 at 14:00.

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

    Default Re: No context switch between Threads and parent ?

    Could we see the exact compilable code instead of that pseudocode? And also add the invocation code.

  3. #3
    Join Date
    Jul 2008
    Posts
    66
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: No context switch between Threads and parent ?

    Thx for answering.

    Sorry I can just add pseudocode.
    Maybe I could explain sth better, when it is not so clear..

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

    Default Re: No context switch between Threads and parent ?

    I'm interested in proper declarations (prototypes) of objects and methods and the way you create and start the thread. You can skip any content which you do not want to expose.

  5. #5
    Join Date
    Jul 2008
    Posts
    66
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: No context switch between Threads and parent ?

    Hi no problem,

    this is my thread-class:
    Qt Code:
    1. #ifndef THREADS_H
    2. #define THREADS_H
    3.  
    4. #include <QThread>
    5.  
    6.  
    7. class serial; //forward decl.
    8. class threads : public QThread
    9. {
    10. Q_OBJECT
    11.  
    12. public:
    13. threads(QObject *parent,bool); //here i push the this-pointer of my serial class, so my Threads can call serial-class methods
    14. ~threads();
    15. threads(threads &);
    16. void stopAll(); // to stop my threads static var is set
    17. protected:
    18. void run();
    19.  
    20. private:
    21. bool readerFlagIsSet,writerFlagIsSet; //ctor will set what kind of thread it is
    22. static bool threadDone;
    23. serial *serialPtr; // pointer to serial class object
    24. };
    25. #endif // THREADS_H
    To copy to clipboard, switch view to plain text mode 
    this is my serial class:

    Qt Code:
    1. #ifndef SERIAL_H
    2. #define SERIAL_H
    3.  
    4. #include <QObject>
    5. #include <QString>
    6. #include <QByteArray>
    7. #include <QList>
    8. #include <QMutex>
    9. #include "define.h"
    10. #include "storage.h"
    11. #include <windows.h>
    12. #include "threads.h" // my thread class (above)
    13. #include "Serial\Serial.h" // this is the foreign serial lib I use
    14.  
    15.  
    16. class serial : public QObject
    17. {
    18. Q_OBJECT
    19.  
    20. public:
    21. serial(QObject *parent);
    22. ~serial();
    23. serial(serial&);
    24. bool openserialport(QString);
    25. bool closeserialport();
    26. QList<QString> scanSerialPorts();
    27. void ResetEvents();
    28.  
    29. //threads fct
    30.  
    31. bool read(); //called by reader-thread in its loop.
    32. //inside the read fct it waits for com events (WaitForMultipleObjects (Win32)) and blocks until data is there
    33. bool isOpen();
    34. bool isWriteJobAvailable(); //called by writer thread, to check if there is data in outgoing queue (to write)
    35. void writeNewJob();// called by writer thread, to get data from queue and call write(QByteArray)
    36. bool write(QByteArray); //called indirectly by writer thread to write data on device
    37.  
    38.  
    39. signals:
    40. void dataIN(); //emit signal when data is read in reader-thread, to inform another thread
    41.  
    42. private:
    43. CSerial cserial; //foreign serial lib I use to access COM port
    44. threads *readerThread,*writerThread; // pointer of type Threads
    45. QByteArray *readBuf;
    46. bool fContinue;
    47. bool portIsOpen;
    48.  
    49. };
    50.  
    51. #endif // SERIAL_H
    To copy to clipboard, switch view to plain text mode 
    In my ctor of my serial class i create two instances, one for readerThread and one for writerThread and start the Threads.

    Ctor of Serial Class:
    Qt Code:
    1. reader = new threads(this,true);
    2. writer = new threads(this,false);
    3.  
    4. reader->start();
    5. writer->start();
    To copy to clipboard, switch view to plain text mode 
    run() of Threads:
    Qt Code:
    1. void threads::run()
    2. {
    3. if(isReaderThread)
    4. while(!threadDone){ //static var which will be set to stop the threads
    5. serialPtr->read(); //serial class fct called with the pointer (got it inside from ctor)
    6. msleep(50);
    7. }
    8.  
    9. if(isWriterThread)
    10. while(!threadDone){
    11. if(serialPtr->isWriteJobAvailable()) //serial class fct called with the pointer (got it inside from ctor)
    12. serialPtr->writeNewJob();
    13. msleep(50);
    14. }
    15. }
    To copy to clipboard, switch view to plain text mode 

    Thanks!

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

    Default Re: No context switch between Threads and parent ?

    I can say one thing - your multi-thread design is full of flaws First of all you access the same object from within more than one thread which is a Bad Thing (TM). Second of all all events for the serial object of yours will be processed in the main thread. I don't know if you actually use events there but based on what you observe, it is highly possible.

    My first and most basic question is - are you sure you really need separate threads for the communication?

  7. #7
    Join Date
    Jul 2008
    Posts
    66
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: No context switch between Threads and parent ?

    First of all you access the same object from within more than one thread which is a Bad Thing
    Maybe I should swap the design. The Threads will get the parent and the serial-classs will be shared between both.
    I must use two threads because of two way communication (overlapped/asynchrone).
    I think that it is common to do it like that in rs232 communication.

    Here you see an example of MS
    http://msdn.microsoft.com/en-us/library/ms810467.aspx
    ......a user interface thread that does memory management, a writer thread that controls all writing, and a reader/status thread that reads data and handles status changes on the port.

    Second of all all events for the serial object of yours will be processed in the main thread. I don't know if you actually use events there but based on what you observe, it is highly possible
    I worried about that. I think swapping would solve this?
    All the access from the threads to the serial-class would be done in the thread context.

    The threads must share just one thing, tha object of the foreign serial library, because this includes all stuff to access com-port.
    Btw, i use this
    http://www.codeproject.com/KB/system/serial.aspx

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

    Default Re: No context switch between Threads and parent ?

    Quote Originally Posted by donglebob View Post
    I must use two threads because of two way communication (overlapped/asynchrone).
    If you use non-blocking IO, you don't have to have any separate threads.

    I think that it is common to do it like that in rs232 communication.
    Common doesn't yet mean correct. Java programmers use a lot of multithreading, so it's common, although in most cases unnecessary when brought to different grounds.

    I worried about that. I think swapping would solve this?
    Swapping in what way?

    The threads must share just one thing, tha object of the foreign serial library, because this includes all stuff to access com-port.
    Btw, i use this
    http://www.codeproject.com/KB/system/serial.aspx
    Have you tried QExtSerialPort?

  9. #9
    Join Date
    Jul 2008
    Posts
    66
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: No context switch between Threads and parent ?

    hi,

    If you use non-blocking IO, you don't have to have any separate threads.
    When I use there functions like "WaitForMultipleObjects", where the reader thread must wait for some events like "data arrived" or sth. like that, it will block the thread until data is available.
    Meanwhile my writer thread could do some IO operations. Thats the reason why I need two threads.


    Swapping in what way?
    Now my threads are children of the the serial-class and they use the pointer of parent to execute parent-functions.
    When I switch parent to children and children to parent, every access to serial-class-object would run in the threads context and not in the main-app.


    Have you tried QExtSerialPort?
    Yes, but it just allows blocking IO. overlapped IO is not implemented yet.
    Last edited by donglebob; 28th October 2008 at 09:49. Reason: reformatted to look better

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

    Default Re: No context switch between Threads and parent ?

    Quote Originally Posted by donglebob View Post
    When I use there functions like "WaitForMultipleObjects", where the reader thread must wait for some events like "data arrived" or sth. like that, it will block the thread until data is available.
    Meanwhile my writer thread could do some IO operations. Thats the reason why I need two threads.
    Ok, but why block at all?

    Yes, but it just allows blocking IO. overlapped IO is not implemented yet.
    Not really. You can check bytesAvailable() and do read() only when there is something to read. In that case it returns immediately. Actually I think it will return immediately regardless if there is anything to read (I'm not sure of that though).

  11. #11
    Join Date
    Jul 2008
    Posts
    66
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: No context switch between Threads and parent ?

    Ok, but why block at all?
    Uhmm, thats how WaitForMultipleObject works ?!?!
    In the samples of MS, which I read, it was always blocked like this.
    I have to wait for events...and if i understood it right the thread must wait somwhere and proceed after the wanted event arrived, to read the data etc... (data can be read immediately or with pending = while pending WaitFor......)

    http://msdn.microsoft.com/en-us/libr...#serial_topic4

    Not really. You can check bytesAvailable() and do read() only when there is something to read. In that case it returns immediately. Actually I think it will return immediately regardless if there is anything to read (I'm not sure of that though).
    As far as I know access to com at "same time" is not allowed in Qextserialport.
    Checked the source again.
    In Win32 it open com-port always with the last parameter NULL, that means
    non-overlapped (synchrone) access.

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

    Default Re: No context switch between Threads and parent ?

    Quote Originally Posted by donglebob View Post
    Uhmm, thats how WaitForMultipleObject works ?!?!
    Ok, but what is the practical reason of doing that? You can use asynchronous communication instead - no blocking, no problems.


    As far as I know access to com at "same time" is not allowed in Qextserialport.
    Checked the source again.
    In Win32 it open com-port always with the last parameter NULL, that means
    non-overlapped (synchrone) access.
    But you only read if there is anything to read thus the call returns at once effectively making it asynchronous (although in theory it is still synchronous). I assure you you can read and write to the port "at the same time". In practice it is not "the same time" as you're using a single thread so you can either read or write because of a single flow, but you can do one immediately after the other. I assure you this works just fine in many-many applications out there.

    Qt does most of it's I/O in buffered mode making it possible for your application to be even more "asynchronous". I don't exactly know how QExtSerialPort is implemented (I'm not very impressed with its quality) but it is known to work so I don't see a reason not to use it. The only thing that sucks with it is the necessity of using timers to poll the port. I've been meaning to fix this myself but currently I don't have time

  13. #13
    Join Date
    Jul 2008
    Posts
    66
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: No context switch between Threads and parent ?

    hi,

    You know I want to use that overlapped IO....and have written the whole sing for that
    It would make me cry to throw all of it away

    Ok, but what is the practical reason of doing that? You can use asynchronous communication instead - no blocking, no problems.
    I think i am using asynchronous comm. with a little break :-)
    Ok maybe I misunderstood sth. How should I inform my thread that there is data? (without using WaitforMultipleObjects)

    I have to react when an event arrives, so I can read from the port.
    Is there another way without WaitFor.......?

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

    Default Re: No context switch between Threads and parent ?

    Use a timer and check bytesAvailable() periodically. It's a bit dirty solution but tends to be acceptable in this case. If you want to synchronize threads, use the API Qt provides instead of the native one. In many cases it will be much faster. WaitForMultipleObjects() is an equivalent of a semaphore. Use QWaitCondition or similar instead.

  15. #15
    Join Date
    Jul 2008
    Posts
    66
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: No context switch between Threads and parent ?

    timer is a real dirty sollution. and doing like this sounds like polling with small breaks. thats what i want to/should avoid. I want to do that event-driven.

    I think i will keep using WaitFor..... and the two threads...
    but i must think on how two give both threads the ability to use the "foreign serial lib instance" to access the port.

    Have to sleep one night..and maybe I will get an idea while sleeping

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

    Default Re: No context switch between Threads and parent ?

    Quote Originally Posted by donglebob View Post
    timer is a real dirty sollution. and doing like this sounds like polling with small breaks. thats what i want to/should avoid. I want to do that event-driven.
    If you expect data to be available very often then this is fine as most of the time the poll will end up positive. If you expect data to be rare, then increase the timeout. Or use an adaptive timeout...

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.