有一个代码示例:
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
谢谢!
答案 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;让线程自己完成 - 但是你无法跟踪你执行此操作的线程。