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. I updated the UI in the sub thread, but the program did not crash
Forum Updated to NodeBB v4.3 + New Features

I updated the UI in the sub thread, but the program did not crash

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 5 Posters 444 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.
  • J Offline
    J Offline
    John Van
    wrote on last edited by
    #1

    Hello everyone,
    I created a timer, move it to a subthread,and update button text when timeout.but the program not crash. Why?

    class A :public QWidget
    {
    public:
        A()
        {
            auto btn = new QPushButton(this);
            auto timer = new QTimer();
            auto thread = new QThread();
            timer->moveToThread(thread);
            thread->start();
            connect(timer, &QTimer::timeout, [=]() {
                btn->setText("11111");
                });
            connect(btn, &QPushButton::clicked, timer, [=]() {
                timer->start(1000);
                });
        }
    };
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
        A a;
        a.show();
        return app.exec();
    }
    
    Axel SpoerlA 1 Reply Last reply
    0
    • J John Van

      Hello everyone,
      I created a timer, move it to a subthread,and update button text when timeout.but the program not crash. Why?

      class A :public QWidget
      {
      public:
          A()
          {
              auto btn = new QPushButton(this);
              auto timer = new QTimer();
              auto thread = new QThread();
              timer->moveToThread(thread);
              thread->start();
              connect(timer, &QTimer::timeout, [=]() {
                  btn->setText("11111");
                  });
              connect(btn, &QPushButton::clicked, timer, [=]() {
                  timer->start(1000);
                  });
          }
      };
      int main(int argc, char *argv[])
      {
          QApplication app(argc, argv);
          A a;
          a.show();
          return app.exec();
      }
      
      Axel SpoerlA Offline
      Axel SpoerlA Offline
      Axel Spoerl
      Moderators
      wrote on last edited by
      #2

      @John-Van
      A lucky day, it seems. Maybe consider purchasing a lottery ticket :-)

      Software Engineer
      The Qt Company, Oslo

      J 1 Reply Last reply
      1
      • Axel SpoerlA Axel Spoerl

        @John-Van
        A lucky day, it seems. Maybe consider purchasing a lottery ticket :-)

        J Offline
        J Offline
        John Van
        wrote on last edited by
        #3

        @Axel-Spoerl That is to say, whether one crash or not depends on luck?

        jsulmJ W 2 Replies Last reply
        0
        • J John Van

          @Axel-Spoerl That is to say, whether one crash or not depends on luck?

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @John-Van It depends on many factors when using threads. Just because this code did not yet lead to any crashes does not mean it is OK to access UI from non-UI threads.

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          Axel SpoerlA 1 Reply Last reply
          3
          • jsulmJ jsulm

            @John-Van It depends on many factors when using threads. Just because this code did not yet lead to any crashes does not mean it is OK to access UI from non-UI threads.

            Axel SpoerlA Offline
            Axel SpoerlA Offline
            Axel Spoerl
            Moderators
            wrote on last edited by
            #5

            @John-Van
            Most of the crashes I saw in this context were concurrent accesses to non-atomic members. I remember a UI randomly crashing, because a worker thread updated a progress bar in the UI. Doesn't seem so far-fetched. When the UI wanted to paint the progress bar, it accessed the progress data member. That worked nicely, unless the UI thread had another update at the same time => booom.

            The more complex a UI gets, the busier is its event loop. That increases the likelihood of data races and crashes. But as @jsulm said, a lot of factors are in play and most of them (e.g. mouse events) are unpredictable. So it's fair to call your day a lucky one :-)

            Software Engineer
            The Qt Company, Oslo

            1 Reply Last reply
            3
            • J John Van has marked this topic as solved on
            • J John Van

              @Axel-Spoerl That is to say, whether one crash or not depends on luck?

              W Offline
              W Offline
              wrosecrans
              wrote on last edited by
              #6

              @John-Van Nothing about it being unsupported guarantees a crash. It's just unsupported with undefined behavior. So if you have a race condition that breaks something, anything can happen. It could crash. Or it could have a subtle issue where data gets overwritten and passwords get silently sent down a network socket. And whatever it appears to be doing today could change tomorrow, or in a moment. Race conditions with multithreading can literally behave completely different if the temperate changes outside, and the CPU clock goes up/down slightly because of the temperature change.

              That it doesn't crash isn't particularly interesting. It's still incorrect.

              1 Reply Last reply
              4
              • S Offline
                S Offline
                SimonSchroeder
                wrote on last edited by
                #7

                @John-Van said in I updated the UI in the sub thread, but the program did not crash:

                That is to say, whether one crash or not depends on luck?

                Yes, it does. From my experience I would say that having luck in this context is mostly deterministic: As long as you don't change your code you could continue to be lucky (and I would claim that the odds are slightly stacked towards not crashing). However, any change in your code (most likely totally unrelated) will lead to crashes eventually.

                BTW, in your case this is really easy to fix. Just write:

                        connect(timer, &QTimer::timeout, this, [=]() {
                            btn->setText("11111");
                            });
                

                The third argument (if present) is a context object. It has a double purpose: 1) If the context object is deleted, the connection will be disconnect (since you rely on capturing this this would be a good idea). 2) More importantly in your case, the lambda will be executed in the thread of the context object (if I'm not mistaken).

                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