Results 1 to 20 of 26

Thread: Thread Safe Queue container....

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Dec 2009
    Posts
    24
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Thread Safe Queue container....

    Quote Originally Posted by wysota View Post
    Attached you will find a real thread-safe queue I just implemented.
    Thanks, I will study this carefully!....

    Quote Originally Posted by wysota View Post
    By the way - your queue doesn't protect you from buffer underruns (or overruns). The fact that you call "isEmpty" or "isFull" is completely meaningless as right when you return some other thread may change its state so you may be adding to a full queue or reading from an empty one. So your queue is not thread-safe in its current form.
    I want to be sure to understand this properly...
    you're saying that a construct like:
    Qt Code:
    1. if(!asyncqueue.isEmpty()) asyncqueue.pull()
    To copy to clipboard, switch view to plain text mode 
    is not safe?
    because between the actual test of emptiness and the actual pull, another thread could have pulled, emptying the queue possibly... and so my pull will fail...
    Is that correct?
    and that's why you added the semaphore on top of the mutex protection?....

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

    Default Re: Thread Safe Queue container....

    Quote Originally Posted by jcox23 View Post
    you're saying that a construct like:
    Qt Code:
    1. if(!asyncqueue.isEmpty()) asyncqueue.pull()
    To copy to clipboard, switch view to plain text mode 
    is not safe?
    Yes, that's correct.

    because between the actual test of emptiness and the actual pull, another thread could have pulled, emptying the queue possibly... and so my pull will fail...
    Exactly.

    and that's why you added the semaphore on top of the mutex protection?....
    Yes, the semaphore makes sure you can't read from an empty queue or write to a full queue. If you try, you will be blocked until you can. This simplifies the code and improves resource usage as your threads won't be spinning around checking if they can access the queue.
    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.


  3. #3
    Join Date
    Dec 2009
    Posts
    24
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Thread Safe Queue container....

    Quote Originally Posted by wysota View Post
    Yes, that's correct.

    Exactly.

    Yes, the semaphore makes sure you can't read from an empty queue or write to a full queue. If you try, you will be blocked until you can. This simplifies the code and improves resource usage as your threads won't be spinning around checking if they can access the queue.
    Thanks very much for the helpful discussion...

    Btw, I got segfaults when trying tryDequeue()...(because I would prefer to have a non blocking behavior)... but don't mind me, maybe I'm not using it right...

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

    Default Re: Thread Safe Queue container....

    The whole point is to block. Non-blocking variants are in general unreliable. And if you don't block and get a buffer overflow, you make your application unstable because you're constantly spinning in the loop waiting for the buffer to be available thus eating cpu power that could be spent on consuming messages from the buffer.

    I can't think of a single situation where you wouldn't want to block (unless blocking was more expensive than a busy loop). If you produce an element and the buffer is full and you don't want to block then what will you do with it? You can only discard it, you can't store it anywhere because you risk falling off a cliff as you are producing elements faster than you can consume them. Blocking is a way to slow down production or consumption in a graceful way.
    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.


  5. #5
    Join Date
    Sep 2009
    Location
    Tashkent, Uzbekistan
    Posts
    107
    Thanks
    1
    Thanked 4 Times in 4 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Thread Safe Queue container....

    Just checked the code. I do suggest to change lock to tryLock for QMutex. Works better because much more predictable with timeouts.

  6. #6
    Join Date
    Dec 2009
    Posts
    24
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Thread Safe Queue container....

    Quote Originally Posted by wysota View Post
    I can't think of a single situation where you wouldn't want to block (unless blocking was more expensive than a busy loop). If you produce an element and the buffer is full and you don't want to block then what will you do with it?
    that's why I wanted to used a growing container...
    the original design, was a growing container, that is only checked by consumers (only 1 or 2 thread) like every second (no cpu hog then)...

    but I'm open to new designs...and will checkout how I can deal with the blocking....
    (i'm mainly concerned on how to kill a thread that is blocking)

    Quote Originally Posted by Tanuki-no Torigava View Post
    Just checked the code. I do suggest to change lock to tryLock for QMutex. Works better because much more predictable with timeouts.
    I'll see how it goes.... but right now in the actual the tryAcquire method is causing segfaults....

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

    Default Re: Thread Safe Queue container....

    Quote Originally Posted by jcox23 View Post
    (i'm mainly concerned on how to kill a thread that is blocking)
    Set a flag that the thread will check right after acquiring a semaphore and release the semaphore so that threads that are being blocked can continue. They should see the flag and exit.
    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.


  8. #8
    Join Date
    Dec 2009
    Posts
    8
    Thanks
    1
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Thread Safe Queue container....

    After checking several interesting threads about data sharing among threads I chose this one to ask for suggestions.

    I am used to POSIX C thread where we can create a pointer to a queue dynamically share it among any other thread, witch could push or pull pointers into or from it.

    I used many times an old C solution where the application creates a queue of struct of pointers with thread id and network data buffer pointer. Upon request the application would create a new thread that would download data from network into a buffer, created dynamically. After download this buffer pointer would be pushed into the queue along with the thread id of the creator. Later a parser thread would process the data according to the thread id, because the parse was URL dependent, and then free the buffer memory.

    I was thinking of doing the same thing with Qt using QQueue<QNetworkReply *> but I read that QObject classes created in one thread shall not have its members called from another thread (believe it has something to do with message loop). Also heard that QNetwork and QSql modules classes shall be used in the same thread they were created.

    From what you've discussed here you came out with a thread safe container but this queue cannot contain pointer to QObject descendant, can it?

    I didn't want to copy all data from QNetworkReply into another container not inherited from QObject to then queue it but I see no other solution.
    So far this is what I came out with:
    1) the thread would dynamically create a QDataStream, wich is not QObject descendanta(is it?), and push all data from QNetworkReply into it.
    2) push QDataStream pointer into queue.
    3) parser thread would pull data out of the shared queue and free the QDataStream after parsing it.

    I think it's a waste of memory and time copying data from one container to another but was the only solution candidate I pondered so far.

    I hope you guys can give me some advices before I start coding this solution. Meanwhile I will take care of the parser function of QDataStream!
    Thanks a lot in advance!
    Last edited by ferrabras; 15th December 2009 at 11:11. Reason: mispelled After (Ater)

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

    Default Re: Thread Safe Queue container....

    You don't need threads to handle multiple network connections with Qt.
    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.


  10. #10
    Join Date
    Dec 2009
    Posts
    8
    Thanks
    1
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Thread Safe Queue container....

    From what I know about QNetworkAccessManager I could connect a void timeout() signal from a timer to a function that requests data and connect a finished(QNetworkReply *) signal from the manager to the function that would use de data. Maybe I create a timer and a manager for each Url, this is also a good idea. I'm sure I could suppress some threads doing it. Thanks.
    Yet I would need the parser/processor to be non blocking so that they don't block the application message loop. So the parser/processor have to be "threaded" and a queue of downloaded data should be available to them. Instead of passing a QNetworkReply pointer I would have to pass a copy of the data itself anyway.

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

    Default Re: Thread Safe Queue container....

    Quote Originally Posted by ferrabras View Post
    Yet I would need the parser/processor to be non blocking so that they don't block the application message loop. So the parser/processor have to be "threaded" and a queue of downloaded data should be available to them.
    How long do you expect the parser to parse the result? Maybe it's so short it's not worth delegating into another thread. Or maybe you can use Qt Concurrent.

    Have you seen the article on [wiki]Keeping the GUI Responsive[/wiki]?
    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.


  12. The following user says thank you to wysota for this useful post:

    bob2oneil (4th April 2011)

  13. #12
    Join Date
    Nov 2010
    Posts
    122
    Thanks
    62
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Thread Safe Queue container....

    Hi wysota, thanks for all that you do to support the Qt community. I just reviewed your fine thread safe queue template. Since this discussion is a few years old, I wonder if there have been any changes to Qt in this time (such as additional thread safe collections or other constructs) that you would utilize for this solution, or if your template implementation is as timely now as when this thread was active? Would you do anything differently with the latest release of Qt?

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

    Default Re: Thread Safe Queue container....

    There have been no changes to Qt in this regard as far as I know.
    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.


  15. The following user says thank you to wysota for this useful post:

    bob2oneil (5th April 2011)

Similar Threads

  1. Is a QProcess thread safe in Qt4?
    By Jay_D in forum Qt Programming
    Replies: 4
    Last Post: 1st September 2009, 16:38
  2. What makes something not thread safe?
    By tgreaves in forum Newbie
    Replies: 9
    Last Post: 20th February 2009, 20:16
  3. KDE/QWT doubt on debian sarge
    By hildebrand in forum KDE Forum
    Replies: 13
    Last Post: 25th April 2007, 06:13
  4. Replies: 10
    Last Post: 20th March 2007, 22:19
  5. Are QHttp n QHttpRequestHeader thread safe?
    By Shambhavi in forum Qt Programming
    Replies: 4
    Last Post: 21st January 2006, 08:33

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.