栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ 主线程退出后,子线程还会存在吗?

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ 主线程退出后,子线程还会存在吗?

答案是:不会

那么我们接下来做做实验(实验内容已放到 github 上,详见此处):

实验1:局部变量线程,detach
#include 
#include 
#include 

#include "GetTimeStamp.h"

void LoopForever() {
    while(true) {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::cout << GetTimeStamp() << std::endl;
    };
}

int main(int argc, char** argv)
{
    std::thread a(LoopForever); // 首先,我们以局部变量的形式创建一个子线程
    a.detach();                 // 然后 detach 子线程
    std::this_thread::sleep_for(std::chrono::seconds(5)); // 等待5秒后,退出进程
    return 0;
}

实验结果如下图所示,5秒后子线程终止。

当进程结束时,所有线程将被中止,不会继续在后台进行。详细可以在《简单了解C语言中主线程退出对子线程的影响》一文中了解。

  实验2:动态创建线程,detach
#include 
#include 
#include 

#include "GetTimeStamp.h"

void LoopForever() {
    while(true) {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        auto stamp = GetTimeStamp();
        std::cout << stamp << std::endl;
    };
}

int main(int argc, char** argv)
{
    auto a = new std::thread(LoopForever); // 首先,我们动态创建一个子线程
    a->detach();                           // 然后 detach 子线程
    std::this_thread::sleep_for(std::chrono::seconds(5)); // 等待5秒后,退出进程
    return 0;
}

  那么使用 new 动态创建线程,是否和局部变量一致呢?答案是肯定的

 实验3:动态创建线程,直接退出进程
#include 
#include 
#include 
#include 

#include "GetTimeStamp.h"

#define DO_NOTHING 1
#define DETACH 1

void LoopForever() {
    std::ofstream of("interview_demo.log", std::ios::trunc);
    while(true) {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        auto stamp = GetTimeStamp();
        std::cout << stamp << std::endl;
        of << stamp << std::endl;
    };
}

int main(int argc, char** argv)
{
    auto a = new std::thread(LoopForever);  // 首先,我们动态创建一个子线程
    std::this_thread::sleep_for(std::chrono::seconds(5));  // 等待5秒后,退出进程
    return 0;
}

使用 new 动态创建线程,直接退出进程的话,与之前的实验结果一致,子线程退出。

实验4:局部变量线程,直接退出进程
#include 
#include 
#include 

#include "GetTimeStamp.h"

void LoopForever() {
    while(true) {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::cout << GetTimeStamp() << std::endl;
    };
}

int main(int argc, char** argv)
{
    std::thread a(LoopForever); // 首先,我们以局部变量的形式创建一个子线程
    std::this_thread::sleep_for(std::chrono::seconds(5)); // 等待5秒后,退出进程
    return 0;
}

 上述代码其实可以编译通过,只是会抛出运行时的异常,这个异常只会在Debug版本被抛出,应该是在局部变量析构时检测到了异常。

而且,线程其实不会立刻终止,而是会在点击对话框中的“中止”按钮前,继续运行。

附 GetTimeStamp.h 代码,用于生成时间戳
#pragma once
#include 
#include 
#include 
#include 
#include 
#include 

static std::string GetTimeStamp()
{
    std::stringstream ss;
    auto now = std::chrono::system_clock::now();
    auto now_t = std::chrono::system_clock::to_time_t(now);
    tm now_tm;

#if defined(_WIN32)
    localtime_s(&now_tm, &now_t);
#elif defined(MS_LINUX)
    localtime_r(&now_t, &now_tm);
#endif

    ss  << std::setfill('0') << std::setw(2) << now_tm.tm_hour
        << ":" << std::setfill('0') << std::setw(2) << now_tm.tm_min
        << ":" << std::setfill('0') << std::setw(2) << now_tm.tm_sec;

    auto tp = now.time_since_epoch();
    auto ms =
        std::chrono::duration_cast(tp)
        - std::chrono::duration_cast(tp);
    ss << "." << std::setfill('0') << std::setw(3) << ms.count();

    return ss.str();
}
小结

子线程在进程退出时会“被退出”,无论是否detach,也无论是否为局部变量(生命周期结束时被析构)。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/954494.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号