Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Italian
  4. L'esecuzione di una routine richiamata da un signal avviene con leggero ritardo

L'esecuzione di una routine richiamata da un signal avviene con leggero ritardo

Scheduled Pinned Locked Moved Solved Italian
7 Posts 3 Posters 2.4k Views
  • 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.
  • B Offline
    B Offline
    bvox123
    wrote on last edited by
    #1

    Buongiorno.
    Ho un modulo thread che fa un loop continuo e si ripete ogni 3 secondi. Dall'interno di questo modulo, emetto un segnale per attivare una routine che aggiorna il form del modulo windowmain. Ho appurato che mentre il modulo thread effettua il quarto loop e lancia il signal per attivare la routine che aggiorna il form, la routine non parte subito, ma si avvia solo quando il loop sarà passato alla quinta iterazione. Dovrei forzare l'esecuzione rigorosamente pedissequa, ma come posso fare una cosa del genere ?

    1. emetto il signal
    2. perde tempo finché la routine non si sarà conclusa
    3. prosegue
    1 Reply Last reply
    0
    • P Offline
      P Offline
      patrik08
      wrote on last edited by patrik08
      #2

      Ciao...
      e com li chiami qui 3 secondi.. in una slot come tipo:

      QTimer::singleShot(i * 1000, this, SLOT(PrintScreen()));
      

      Di regola funzionano bene in codice ordinato e richiamare funzioni ogni 500 millisecondi a me non danno mai problemi .. come del tipo di attesa di conversione dei file...

      1 Reply Last reply
      0
      • B Offline
        B Offline
        bvox123
        wrote on last edited by
        #3

        Ho questa situazioni.

        1. Il main attiva un thread e lo rende a loop infinito così:
            HRnet_0490 = new HRnet_0490_Qthread;
            HRnet_0500 = new HRnet_0500_Elaborazione;
            HRnet_0500->moveToThread(HRnet_0490);
            HRnet_0490->start();
            QObject::connect(HRnet_0490, SIGNAL (started()), HRnet_0500, SLOT (emitThread()));
        

        Il modulo HRnet_0500 gira per tutta l'esecuzione del programma ed è in attesa che si schiacci un pulsante che avvii l'esecuzione di alcune istruzioni finché non si ripigia il tasto per metterlo in attesa. Come ultime istruzioni di questo gruppo while (true) ho un msleep(3000) per farlo "looppare" dopo 3 secondi.
        Ad ogni fase del loop, il programma va ad incrementare l'indice di una matrice di molti elementi e, solo in determinati casi, scatenare la scrittura di dati a video.
        Ebbene, nel momento in cui vado ad elaborare l'incremento dell'indice e popolare di dati la matrice, ho l'istruzione "int ultind = HRnet_0110->LeggiProgrEstrattoFISSO();" che mi dà nella variabile ultind il valore 5. Elabora, fa calcoli e decide di visualizzare il risultato, quindi lancia un "emit SignalMostra". All'interno del modulo mainwind c'è lo slot SignalMostra e la prima istruzione di questo slot è l'identica istruzione vista prima: ovvero "int ultindprodotto = HRnet_0110->LeggiProgrEstrattoFISSO();" ma, stranamente, consultando il valore di questo ultindprodotto lo trovo impostato a 4: come se stesse eseguendo la routine ancor prima che sia finita la popolazione del quinto indice.
        Però, mi sa che sto inventando la macchina del tempo: richiamo una routine alla quinta iterazione e questa dice che mi trovo ancora alla quarta. :-)
        Scherzi a parte, evidentemente l'avvio dello slot per la visualizzazione dei dati non riesce a tenere conto che l'elaborazione si trova già all'elemento successivo. Non so che fare.

        1 Reply Last reply
        0
        • P Offline
          P Offline
          patrik08
          wrote on last edited by
          #4

          Guarda.... la strada bella è sempre organizzata pulita controllata nei minimi dettagli con molta passione.
          Tu invece per venire a capo devi traciare tutti i percorsi nel minimo dettaglio e seguire bene i SLOT che questi sono precisi...
          Vale a dire debug & debug fino che tutto fila dritto...
          E tutto cosa posso dirti non vedendo molto codice...
          ma mi sembra strano che aspetti un emit da HRnet_0490 semmai è il Worker Thread ch dice he ha finito...
          saluti....

          #if 0 //// 1 or 0
          #define EPUBDEBUG qDebug
          #define STAGE 1
          #else
          #define EPUBDEBUG         \
            if (0)                              \
            qDebug
          #define STAGE 0
          #endif
          
          1 Reply Last reply
          0
          • B Offline
            B Offline
            bvox123
            wrote on last edited by
            #5

            Grazie. Proverò ma mi vedo su una strada molto tortuosa.

            1 Reply Last reply
            0
            • VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by
              #6

              Credo che qui il problema e' che vorresti che Qt gestisse la sincronizzazione dei thread, cosa che non puo' fare.

              Per farti capire cosa sta succedendo devi avere l'intuizione di come funziona l'event loop in Qt.
              QApplication::exec(), QEventLoop::exec(), e QThread::exec() fannu tutti partire un event loop che puoi immaginare sia una cosa tipo:while(true) QApplication::processEvents();

              Quando connetti un segnale dal thread2 al thread principale (gui thread) e questo viene emesso, viene automaticamente messo in coda (Qt::QueuedConnection) nel gui therad e viene eseguito non appena quel thread raggiunge l'istruzione QApplication::processEvents();. Questo perche' il thread2 non ha idea di cosa stia facendo il gui thread, quindi gli dice "quando hai tempo, processa quello slot", questo evita race conditions. Non c'e' modo di evitare (in generale) race conditions se vuoi che lo slot venga eseguito istantaneamente. Puoi forzare la connessione tra signal e slot ad essere istantanea aggiungendo Qt::DirectConnection come ultimo argomento a connect() ma questo significa che sta a te assicurarti di non avere race conditions usando mutex (std::mutex, QMutex, QReadWriteBlock, etc.) o atomic (std::atomic<T>)

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              1 Reply Last reply
              0
              • B Offline
                B Offline
                bvox123
                wrote on last edited by
                #7

                Grazie. Ho capito che devo studiare di più.

                1 Reply Last reply
                0

                • Login

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