std :: thread请解释输出

时间:2015-12-04 00:21:44

标签: 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,MULTITHREADING!”:

 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

谢谢!

2 个答案:

答案 0 :(得分:2)

这是罪魁祸首:

      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();
  }
}

答案 1 :(得分:0)

正如评论员所说,&#34;加入()&#34;阻止主线程,直到你新生成的线程完成,所以当你打电话给你的&#34;开始&#34; function - 它创建线程然后等待它完成。

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

你可以使用&#34; std :: thread :: detach&#34;让线程自己完成 - 但是你无法跟踪你执行此操作的线程。