为什么我的线程不能在后台运行?

时间:2017-08-15 20:24:24

标签: c++ multithreading c++11 parallel-processing

在下面的列表中,我希望当我在创建线程的行之后调用t.detach()时,线程t将在后台运行,而printf("quit the main function now \n")将被调用然后main将退出。

#include <thread>
#include <iostream>

void hello3(int* i)
{

    for (int j = 0; j < 100; j++)
    {
        *i = *i + 1;
        printf("From new thread %d \n", *i);
        fflush(stdout);

    }

    char c = getchar();
 }

int main()
{
    int i;
    i = 0;
    std::thread t(hello3, &i);
    t.detach();
    printf("quit the main function now \n");
    fflush(stdout);
    return 0;
}

然而,从它在屏幕上打印的内容来看并非如此。它打印

From new thread 1
From new thread 2
....
From new thread 99
quit the main function now.

看起来main函数在执行命令printf("quit the main function now \n");之前等待线程完成并退出。

你能解释一下它为什么吗?我在这里缺少什么?

4 个答案:

答案 0 :(得分:4)

问题是你的线程太快了。

在主要有机会继续之前,它能够打印所有100个字符串。

尝试让线程变慢,你会在线程之前看到主printf

答案 1 :(得分:3)

根据您的操作系统调度,它会发生。此外,线程的速度也会影响输出。如果您停止线程(例如,将100更改为500),您将首先看到该消息。

我刚刚执行了代码并且现在退出了主要功能。&#34;消息首先出现 ,如下所示:

quit the main function now 
From new thread 1 
From new thread 2 
From new thread 3 
From new thread 4 
...

你对detach

是正确的
  

从调用线程中分离由对象表示的线程,允许它们彼此独立地执行。

但这并不能保证消息&#34;现在退出主要功能&#34;将首先出现,尽管很可能。

答案 2 :(得分:1)

  

看起来main函数在执行命令printf之前等待线程完成(“现在退出main函数\ n”);并退出。

这是因为当您创建一个线程时,它会被调度执行,但跨线程的事件顺序不再是顺序的,有序的或确定的。在程序的某些运行中,hello3的输出将在quit the main function now之前发生,在某些运行中它将在之后打印,并且在某些运行中,输出将是交错的。这是一种未定义的行为,通常称为“竞争条件”。在大多数(但不是全部)情况下,hello3的输出打印最后,因为在设置线程时会有一些开销(因操作系统和处理器而异),所以需要几微秒正确构建线程并准备执行需要花费很长时间才能使printf函数中的main语句在线程准备好运行之前已经有时间执行并flush

如果你想要明确证明事情是同时运行的,你应该在quit语句之前在主线程中添加更多的工作,这样在线程准备开始执行之前主函数就不可能完成。

答案 3 :(得分:0)

您的代码存在两个主要问题:

  1. 一旦 main 函数退出,您就会有未定义的行为,因为分离线程引用的变量 i 不再存在。

  2. 一旦 main 函数返回后整个过程结束,分离的线程也会死亡。