Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. General talk
  3. Brainstorm
  4. changing from 1:1 to 1:many
Forum Updated to NodeBB v4.3 + New Features

changing from 1:1 to 1:many

Scheduled Pinned Locked Moved Solved Brainstorm
12 Posts 3 Posters 1.7k Views 3 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.
  • SGaistS SGaist

    Hi,

    How are you communicating with your devices ?

    mzimmersM Offline
    mzimmersM Offline
    mzimmers
    wrote on last edited by
    #3

    @SGaist oh yeah, I guess that would be helpful: UDP sockets, usually multicast. I think I can make things work with a common communications layer; it's just the "work" work that might need to be divvied up.

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #4

      Are you sure UDP is the right tool to push firmware updates ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      1
      • mzimmersM Offline
        mzimmersM Offline
        mzimmers
        wrote on last edited by
        #5

        I misspoke...we use UDP for other information, but we use TCP for the OTA. It goes through some rudimentary encryption as well.

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #6

          Ok, then it sounds like you could have some sort of task manager. Maybe QtConcurrent could the job depending on what these tasks are.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          1
          • mzimmersM mzimmers

            Hi all -

            As many of you know, I've been developing an app that allows a user to configure and monitor a remote device. When this project began, it was anticipated that my app would be used to deal with one device at a time.

            Now, sales is asking for "mass processing" features. In other words, from a list of devices (which I already have), select some and push a button, and something (like a firmware OTA update) happens to all the selected devices.

            My app wasn't architected for this, and I'm wondering how best to go about it. My first thought was to create new threads for each selected device, and write wrappers for whatever functionality I need to "mass." This could get messy...I welcome any ideas on this.

            Thanks...

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

            @mzimmers said in changing from 1:1 to 1:many:

            My app wasn't architected for this, and I'm wondering how best to go about it. My first thought was to create new threads for each selected device, and write wrappers for whatever functionality I need to "mass." This could get messy...I welcome any ideas on this.

            As each job sounds to be completely independent of each other piece of work, what @SGaist says sounds most sensible to me - putting the work into a queue and spreading it over a thread pool. Implementations can vary depending on the required complexity and the specifics.

            Creating one thread for each piece is borderline terrible. Threads can be expensive, and you don't need that many anyway. You could even just run one thread that does all the work, which'd be my first go-to.

            Read and abide by the Qt Code of Conduct

            mzimmersM 1 Reply Last reply
            1
            • kshegunovK kshegunov

              @mzimmers said in changing from 1:1 to 1:many:

              My app wasn't architected for this, and I'm wondering how best to go about it. My first thought was to create new threads for each selected device, and write wrappers for whatever functionality I need to "mass." This could get messy...I welcome any ideas on this.

              As each job sounds to be completely independent of each other piece of work, what @SGaist says sounds most sensible to me - putting the work into a queue and spreading it over a thread pool. Implementations can vary depending on the required complexity and the specifics.

              Creating one thread for each piece is borderline terrible. Threads can be expensive, and you don't need that many anyway. You could even just run one thread that does all the work, which'd be my first go-to.

              mzimmersM Offline
              mzimmersM Offline
              mzimmers
              wrote on last edited by
              #8

              @kshegunov so I've read a little of the documentation on QtConcurrent. If I get the gist of it, I'd create a new class, RemoteDevice, which would be the basis of my sequence. Each element in my sequence would represent one (selected) remote device. The function specified in the mapping call would be something that receives signals from the worker thread, and acts on them. Is this even close to being correct?

              Thanks...

              kshegunovK 1 Reply Last reply
              0
              • mzimmersM mzimmers

                @kshegunov so I've read a little of the documentation on QtConcurrent. If I get the gist of it, I'd create a new class, RemoteDevice, which would be the basis of my sequence. Each element in my sequence would represent one (selected) remote device. The function specified in the mapping call would be something that receives signals from the worker thread, and acts on them. Is this even close to being correct?

                Thanks...

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

                @mzimmers said in changing from 1:1 to 1:many:

                @kshegunov so I've read a little of the documentation on QtConcurrent. If I get the gist of it, I'd create a new class, RemoteDevice, which would be the basis of my sequence. Each element in my sequence would represent one (selected) remote device. The function specified in the mapping call would be something that receives signals from the worker thread, and acts on them. Is this even close to being correct?

                Hm, I don't understand your explanation, so I can't say if it's correct. It can go as simple as this:

                class PushToDevice
                {
                public:
                    PushToDevice(...); //< Save some arguments you may need when it executes
                    
                    void operator () ()
                    {
                        // Do whatever is you do in the thread
                    }
                }
                
                QtConcurrent::run(PushToDevice(...));
                

                Alternatively:

                class PushToDevice : public QRunnable
                {
                    // ... Save arguments through the constructor or w/e else you need
                    void run()
                    {
                         // Do whatever it is in the thread
                    }
                };
                
                QThreadPool * pool = QThreadPool::globalInstance();
                pool->start(new PushToDevice(...));
                

                Something along these lines is what I was thinking about.

                Note: Opening sockets or db connections should happen from within the thread they're intended to be used

                Read and abide by the Qt Code of Conduct

                mzimmersM 1 Reply Last reply
                4
                • kshegunovK kshegunov

                  @mzimmers said in changing from 1:1 to 1:many:

                  @kshegunov so I've read a little of the documentation on QtConcurrent. If I get the gist of it, I'd create a new class, RemoteDevice, which would be the basis of my sequence. Each element in my sequence would represent one (selected) remote device. The function specified in the mapping call would be something that receives signals from the worker thread, and acts on them. Is this even close to being correct?

                  Hm, I don't understand your explanation, so I can't say if it's correct. It can go as simple as this:

                  class PushToDevice
                  {
                  public:
                      PushToDevice(...); //< Save some arguments you may need when it executes
                      
                      void operator () ()
                      {
                          // Do whatever is you do in the thread
                      }
                  }
                  
                  QtConcurrent::run(PushToDevice(...));
                  

                  Alternatively:

                  class PushToDevice : public QRunnable
                  {
                      // ... Save arguments through the constructor or w/e else you need
                      void run()
                      {
                           // Do whatever it is in the thread
                      }
                  };
                  
                  QThreadPool * pool = QThreadPool::globalInstance();
                  pool->start(new PushToDevice(...));
                  

                  Something along these lines is what I was thinking about.

                  Note: Opening sockets or db connections should happen from within the thread they're intended to be used

                  mzimmersM Offline
                  mzimmersM Offline
                  mzimmers
                  wrote on last edited by
                  #10

                  @kshegunov I'm intrigued by the QtConcurrent namespace approach. A few questions/comments:

                  • I've never seen the "void operator () ()" construct before -- I read a little about it, but I'm not sure I fully understand it. What is its advantage over a traditional function?

                  • in your first example, where is the PushToDevice object instantiated -- does QtConcurrent:::run() do this for you?

                  • I take it that QtConcurrent::run() would typically be run from a worker thread, yes?

                  • Your comment about opening sockets in the thread that will use them is interesting. Is this a Qt-specific guideline? I ask because I wrote the firmware on my target device specifically NOT to do this. (FreeRTOS doesn't have threads, but it does have tasks.) I have a socket task that manages the state of all the sockets. Access to these sockets is through queue messages. This way I can provide a common interface to the socket layer for all the other tasks.

                  kshegunovK 1 Reply Last reply
                  0
                  • mzimmersM mzimmers

                    @kshegunov I'm intrigued by the QtConcurrent namespace approach. A few questions/comments:

                    • I've never seen the "void operator () ()" construct before -- I read a little about it, but I'm not sure I fully understand it. What is its advantage over a traditional function?

                    • in your first example, where is the PushToDevice object instantiated -- does QtConcurrent:::run() do this for you?

                    • I take it that QtConcurrent::run() would typically be run from a worker thread, yes?

                    • Your comment about opening sockets in the thread that will use them is interesting. Is this a Qt-specific guideline? I ask because I wrote the firmware on my target device specifically NOT to do this. (FreeRTOS doesn't have threads, but it does have tasks.) I have a socket task that manages the state of all the sockets. Access to these sockets is through queue messages. This way I can provide a common interface to the socket layer for all the other tasks.

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

                    @mzimmers said in changing from 1:1 to 1:many:

                    I've never seen the "void operator () ()" construct before -- I read a little about it, but I'm not sure I fully understand it. What is its advantage over a traditional function?

                    It's the old way of writing a lambda (a.k.a. functor object). The difference from a regular function is that you have a state attached to the actual function.

                    in your first example, where is the PushToDevice object instantiated -- does QtConcurrent:::run() do this for you?

                    No, you pass it to QtConcurrent::run, I've used an rvalue (a temporary) here just for brevity and've passed it by value.

                    I take it that QtConcurrent::run() would typically be run from a worker thread, yes?

                    When the time comes, yes. It's queued and processed when a timeslice becomes available in the thread pool.

                    Is this a Qt-specific guideline?

                    Yes, a Qt-specific requirement and I didn't mean sockets as unix descriptors, but sockets as QTcpSocket and such.

                    I ask because I wrote the firmware on my target device specifically NOT to do this.

                    Can't comment. I've not worked with RTOSes, but Qt's sockets can be somewhat finicky when you need to get threads involved. One such example is when you develop a threaded server. What one has to do (as described in the docs) is to transfer the descriptor to the correct thread and then initialize the socket object. And if a socket is in a specific thread it's a bit different than the regular QObject as it can't be freely pushed into another thread. A rather inconsistent behaviour compared to other (regular) QObjects, but that's an implementation limitation unfortunately.

                    Read and abide by the Qt Code of Conduct

                    1 Reply Last reply
                    1
                    • mzimmersM Offline
                      mzimmersM Offline
                      mzimmers
                      wrote on last edited by
                      #12

                      Thanks for the suggestions. I'm sure I'll have more questions about implementation, but as the original issue has been answered, I'm marking this as solved.

                      1 Reply Last reply
                      1

                      • Login

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