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 443 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 8 Dec 2023, 06:23 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();
    }
    
    A 1 Reply Last reply 8 Dec 2023, 06:31
    0
    • J John Van
      8 Dec 2023, 06:23

      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();
      }
      
      A Offline
      A Offline
      Axel Spoerl
      Moderators
      wrote on 8 Dec 2023, 06:31 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 8 Dec 2023, 07:18
      1
      • A Axel Spoerl
        8 Dec 2023, 06:31

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

        J Offline
        J Offline
        John Van
        wrote on 8 Dec 2023, 07:18 last edited by
        #3

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

        J W 2 Replies Last reply 8 Dec 2023, 07:19
        0
        • J John Van
          8 Dec 2023, 07:18

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

          J Offline
          J Offline
          jsulm
          Lifetime Qt Champion
          wrote on 8 Dec 2023, 07:19 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

          A 1 Reply Last reply 8 Dec 2023, 07:40
          3
          • J jsulm
            8 Dec 2023, 07:19

            @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.

            A Offline
            A Offline
            Axel Spoerl
            Moderators
            wrote on 8 Dec 2023, 07:40 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 8 Dec 2023, 07:46
            • J John Van
              8 Dec 2023, 07:18

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

              W Offline
              W Offline
              wrosecrans
              wrote on 8 Dec 2023, 22:01 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 11 Dec 2023, 08:04 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

                1/7

                8 Dec 2023, 06:23

                • Login

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