Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Queue enque and deque thread safe
Forum Updated to NodeBB v4.3 + New Features

Queue enque and deque thread safe

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 3 Posters 1.3k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    kubikula
    wrote on last edited by kubikula
    #1

    Hi,
    I have some ambiguities about thread safe and Queue.
    I read doc and there is note: All functions in this class are reentrant. That is clear.

    I need shared queue with one producer and one consumer. I used the simple example with two semaphores and change array to queue. With array is it clear, but with queue there theoretical should be enqueue and dequeue simultaneously. Always each on different item (so on different memory adress) in queue. Is it problem?

    If yes, can I use QSharedPointer to solve my problem ?
    If I understood correctly then I need two QSharedPointer reference to same queue for thread safe. Is it right?
    I would like to avoid using a mutex for locking queue.

    const int queueSize = 100;
    QQueue<int> queue;
    
    QSemaphore freeItems(queueSize);
    QSemaphore usedItems;
    
    class Producer : public QThread
    {
    public:
        void run() override
        {
          freeItems.acquire();
          queue.enqueue(1); 
          usedItems.release();
        }
    
    class Consumer : public QThread
    {
        Q_OBJECT
    public:
        void run() override
        {
          usedItems.acquire();
          cout << queue.dequeue() << Qt::endl;
          freeItems.release();
        };
    

    Thank you for your help

    kshegunovK 1 Reply Last reply
    0
    • gde23G Offline
      gde23G Offline
      gde23
      wrote on last edited by
      #2

      You should leave the semaphote/mutex there since the enqueue/dequeue will probably need to access the same counter or whatever is in the queue to count the items in there.
      Furthermore, the enqueueing/dequeueing is just a few processor cycles, so you won't loose any speed on this.
      The costly computaitons that you want to do on your items then can be performed after the release of the semaphore. However here you have to be sure to only work on one item at a time unless there are some mechanism to make this thread safe.

      Shared pointer has nothing to do with this. its just a smart pointer.

      1 Reply Last reply
      0
      • K kubikula

        Hi,
        I have some ambiguities about thread safe and Queue.
        I read doc and there is note: All functions in this class are reentrant. That is clear.

        I need shared queue with one producer and one consumer. I used the simple example with two semaphores and change array to queue. With array is it clear, but with queue there theoretical should be enqueue and dequeue simultaneously. Always each on different item (so on different memory adress) in queue. Is it problem?

        If yes, can I use QSharedPointer to solve my problem ?
        If I understood correctly then I need two QSharedPointer reference to same queue for thread safe. Is it right?
        I would like to avoid using a mutex for locking queue.

        const int queueSize = 100;
        QQueue<int> queue;
        
        QSemaphore freeItems(queueSize);
        QSemaphore usedItems;
        
        class Producer : public QThread
        {
        public:
            void run() override
            {
              freeItems.acquire();
              queue.enqueue(1); 
              usedItems.release();
            }
        
        class Consumer : public QThread
        {
            Q_OBJECT
        public:
            void run() override
            {
              usedItems.acquire();
              cout << queue.dequeue() << Qt::endl;
              freeItems.release();
            };
        

        Thank you for your help

        kshegunovK Offline
        kshegunovK Offline
        kshegunov
        Moderators
        wrote on last edited by kshegunov
        #3

        @kubikula said in Queue enque and deque thread safe:

        If yes, can I use QSharedPointer to solve my problem ?

        No.

        If I understood correctly then I need two QSharedPointer reference to same queue for thread safe. Is it right?

        Absolutely not.

        I would like to avoid using a mutex for locking queue.

        Why? The mutex is a simpler semaphore, you're already using two semaphores, so how's a mutex a problem?

        You probably want something like this (I write off the top of my head, so you should test and fix so it compiles):

        QSemaphore availableItems;
        QMutex queueLock;
        
        void Producer::run()
        {
            QMutexLocker locker(&queueLock);
            queue.enqueue( ... );
            availableItems.release();
        }
        
        void Consumer::run()
        {
            availableItems.acquire();
            QMutexLocker locker(&queueLock);
            if (!queue.size())
                return 0; // < Allow to exit gracefully
        
            ... = queue.dequeue();
        }

        Read and abide by the Qt Code of Conduct

        1 Reply Last reply
        2

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved