【问题标题】:Why does my thread not run in background?为什么我的线程不在后台运行?
【发布时间】:2017-08-15 20:24:24
【问题描述】:

在下面的清单中,我希望当我在创建线程的行之后调用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"); 并退出之前一直等到线程完成。

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

【问题讨论】:

  • 将 100 增加到几千,看看会发生什么。话虽如此,当我在 ideone 上对其进行测试时,该线程从未打印任何内容。
  • 仅仅因为你启动了一个线程,没有任何东西可以保证它会并行运行——它可能相对于你的主线程完全串行执行并且仍然是一个完全有效的线程(例如一个不经常切换任务/线程的单个 cpu 机器)。不要假设您无法保证的事情(如并发)。

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


【解决方案1】:

问题是你的线程太快了。

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

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

【讨论】:

    【解决方案2】:

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

    我刚刚执行了代码并“现在退出主函数”。消息出现在第一个,像这样:

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

    detach你说得对:

    将对象所代表的线程从调用线程中分离出来,让它们彼此独立执行。

    但这并不能保证“现在退出主函数”的消息会首先出现,尽管很有可能。

    【讨论】:

      【解决方案3】:

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

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

      如果您想要明确的证据表明事情正在并发运行,您应该在退出语句之前在主线程中添加更多工作,这样主函数就不太可能在线程准备好开始执行之前完成。

      【讨论】:

        【解决方案4】:

        您的代码有两个主要问题:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-01-13
          • 1970-01-01
          • 2015-01-03
          • 1970-01-01
          相关资源
          最近更新 更多