c++ - std::thread 请解释输出

标签 c++ multithreading

有一个代码示例:

  class MY_Timer
    {
    // ...
    void start(const UInt timeOut, const UInt events, CALLBACK_TARGET reciever)
       {
          cout << __FUNCTION__ << " " << timerName << endl;

          if (active) return;
          if ((0u == timeOut) || (0u == events)) return;
          if (nullptr == reciever) return;

          interval = timeOut;
          eventsAmount = events;
          active = true;
          cb_target = reciever;

          thread clockieThread(&MY_Timer::clockie, this); // комментарий
          clockieThread.join();
       };

    private:
       void clockie()
       {
          while (eventsAmount--)
          {
             Sleep(interval);
             cb_target(timerName, eventsAmount);
          }

          active = false;
       }
    // ...
    };

    void target(const char * timerName, const UInt data)
    {
       cout << timerName << " DATA: " << data << endl;
    }

    int main()
    {
       MY_Timer * tOne = new MY_Timer("ALPHA");
       MY_Timer * tTwo = new MY_Timer("OMEGA");

       tOne->start(200, 10, &target);
       tTwo->start(300, 20, &target);
    }

这是输出的样子:

MY_Timer::start ALPHA
ALPHA DATA: 9
ALPHA DATA: 8
ALPHA DATA: 7
ALPHA DATA: 6
ALPHA DATA: 5
ALPHA DATA: 4
ALPHA DATA: 3
ALPHA DATA: 2
ALPHA DATA: 1
ALPHA DATA: 0
MY_Timer::start OMEGA
OMEGA DATA: 9
OMEGA DATA: 8
OMEGA DATA: 7
OMEGA DATA: 6
OMEGA DATA: 5
OMEGA DATA: 4
OMEGA DATA: 3
OMEGA DATA: 2
OMEGA DATA: 1
OMEGA DATA: 0

您能否解释一下为什么这种代码行为就像只有一个执行流程。我认为输出会与来自两个线程的消息混合在一起,就像我这样做一样:

void foo(const char * name, int interval) 
{
   int step = 10;
   while (step--)
   {
      Sleep(interval);
      cout << name << " step: " << step << endl;
   }
}

int main()
{
   thread t1(foo, "ALPHA", 200);
   thread t2(foo, "OMEGA", 300);
   t1.join();
   t2.join();

   return 0;
}

输出将类似于:“OMG,多线程!”:

 ALPHA step: 9
    OMEGA step: 9
    ALPHA step: 8
    OMEGA step: 8
    ALPHA step: 7
    ALPHA step: 6
    OMEGA step: 7
    ALPHA step: 5
    OMEGA step: 6
    ALPHA step: 4
    ALPHA step: 3
    OMEGA step: 5
    ALPHA step: 2
    OMEGA step: 4
    ALPHA step: 1
    ALPHA step: 0
    OMEGA step: 3
    OMEGA step: 2
    OMEGA step: 1
    OMEGA step: 0

谢谢!

最佳答案

这是罪魁祸首:

      thread clockieThread(&MY_Timer::clockie, this); // комментарий
      clockieThread.join();

如果您考虑一下它的作用并扩展您的代码,结果将看起来像这样:

int main()
{
   MY_Timer * tOne = new MY_Timer("ALPHA");
   MY_Timer * tTwo = new MY_Timer("OMEGA");

   tOne->start(200, 10, &target);
   // clockieThread1 created
   // clockieThread1 joined (blocks until complete)
   tTwo->start(300, 20, &target);
   // clockieThread2 created
   // clockieThread2 joined (blocks until complete)

   return 0;
}

您在创建线程后立即加入线程,因此它会阻塞一切,直到线程结束。

您可能想要的是让线程成为该类的成员,您可以开始/加入它。

class MY_Timer
{
  thread clockieThread;
  ...
  void start(const UInt timeOut, const UInt events, CALLBACK_TARGET reciever)
     ...
     clockieThread = thread(&MY_Timer::clockie, this);
     // Remove the clockieThread.join() here
  }

  void join() {
    clockieThread.join();
  }
}

然后通过该更改,您可以执行以下操作:

int main()
{
   MY_Timer * tOne = new MY_Timer("ALPHA");
   MY_Timer * tTwo = new MY_Timer("OMEGA");

   tOne->start(200, 10, &target);
   tTwo->start(300, 20, &target);
   tOne->join();
   tTwo->join();

   return 0;
}

如果你想完全消除 tOne->join() 调用,你可以在类的析构函数中进行连接:

class MY_Timer
{
  ...
  ~MY_Timer() {
    clockieThread.join();
  }
}

关于c++ - std::thread 请解释输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34078798/

相关文章:

c++ - 从 int 到 void * 的转换是可能的吗?

c++ - 在容器中存储常量字符串文字

c++ - Base64 加密/解密 (C++ Builder XE)

c++ - vector 的 emplace_back

java - 在 Java 中为生产者/消费者模式创建同步缓冲区

android - 应用程序关闭时线程是否会停止?

c# - 使用多个 'while()' 循环是不好的做法吗?

c++ - 带有 make_unique 和 emplace_back 的简单结构

Python - 如何使以下函数线程化?

android - 应用程序停止后线程仍在运行