【C++多线程编程】(五)之 线程生命周期管理join() 与 detach()

2023-12-22 07:20

本文主要是介绍【C++多线程编程】(五)之 线程生命周期管理join() 与 detach(),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在C++中,std::thread 类用于创建和管理线程。std::thread 提供了两种主要的方法来控制线程的生命周期:joindetach

  • detach方式,启动的线程自主在后台运行,当前的代码继续往下执行,不等待新线程结束。
  • join方式,等待启动的线程完成,才会继续往下执行。

需要注意的是,一旦线程被分离,就无法再对其调用 join 方法,否则会导致程序终止。因此,在使用 detach 方法时,需要确保主线程不再依赖于被分离的线程的执行。

join( )

  • join 方法用于等待一个线程的完成。当一个线程调用另一个线程的 join 方法时,调用线程将被阻塞,直到被调用的线程执行完成。这样做的主要目的是确保主线程等待所有其他线程完成后再继续执行。

  • 使用 join 的主要目的是确保在主线程继续执行之前,所有其他线程都已经完成。这种阻塞行为是为了协调不同线程之间的执行顺序,以避免并发问题或确保线程的执行顺序符合程序的逻辑。

  • 当然,要注意使用 join 时可能引入的潜在问题,比如死锁(如果两个线程相互等待对方完成),因此在使用 join 时需要仔细考虑线程之间的交互。

示例代码如下:

#include <iostream>
#include <thread>void myFunction() {// 线程执行的代码std::cout << "Thread Function\n";
}int main() {std::thread myThread(myFunction);// 主线程等待 myThread 执行完成myThread.join();std::cout << "Main Function\n";return 0;
}

在上面的例子中,main 函数中的线程通过 join 方法等待 myThread 的执行完成。

join后面的代码不会被执行,除非子线程结束。

detach( )

detach()std::thread 类的一个成员函数,用于将线程与主线程分离。当调用 detach() 后,主线程不再等待被分离的线程执行完成,而是让它在后台运行。

下面是 detach() 的一些关键点:

  1. 分离线程: 调用 detach() 后,当前线程对象所代表的线程就被分离了。这意味着主线程不再对该线程进行管理,不再等待它的完成。

  2. 后台运行: 被分离的线程将在后台运行,即使主线程退出,被分离的线程仍然可以继续执行。

  3. 资源回收: 当被分离的线程运行结束时,其资源(如线程的栈空间等)会被自动释放,不需要手动调用 join() 来等待线程结束。线程的资源将由操作系统自动回收。

  4. 潜在问题: 使用 detach() 带来的便利性是,主线程可以继续执行其他任务而不必等待被分离的线程完成。然而,这也引入了一些潜在的问题,比如可能导致资源泄漏、难以追踪线程的状态等。

    在实际应用中,除非你确切地知道你需要分离线程,并且明白潜在的问题,否则最好使用 join() 等待线程的完成,以避免可能的资源泄漏和其他难以调试的问题。

如:典型UI界面线程可以剥离到后台

如果主线程运行结束,程序则结束

// 线程函数
void myThreadFunc(int n) {}int main()
{// 创建并启动一个线程std::thread myThread(myThreadFunc, 5);myThread.detach();// 主线程继续执行其他任务std::cout << "Hello from the main thread!" << std::endl;// 注意:不再调用 join(),因为线程已被分离return 0;
}

判断线程是否被join( )

在C++中,可以使用joinable方法来检查一个std::thread对象是否可以被joinjoinable方法返回一个bool值,如果线程可以被join,则返回true,否则返回false

在这个例子中,首先创建了一个线程myThread,然后通过joinable方法检查该线程是否可以被join。如果线程是joinable的,就安全地调用了join方法。这是为了防止在不安全的状态下调用join,因为一旦线程被分离,就无法再调用join

总之,使用joinable可以在调用join之前检查线程的状态,以确保线程在调用join时处于正确的可合并状态。

#include <iostream>
#include <thread>void myFunction() {// 线程执行的代码std::cout << "Thread Function\n";
}int main() {std::thread myThread(myFunction);if (myThread.joinable()) {std::cout << "Thread is joinable\n";// 可以安全地调用 joinmyThread.join();} else {std::cout << "Thread is not joinable\n";}std::cout << "Main Function\n";return 0;
}

这篇关于【C++多线程编程】(五)之 线程生命周期管理join() 与 detach()的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/523059

相关文章

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

Spring Boot3虚拟线程的使用步骤详解

《SpringBoot3虚拟线程的使用步骤详解》虚拟线程是Java19中引入的一个新特性,旨在通过简化线程管理来提升应用程序的并发性能,:本文主要介绍SpringBoot3虚拟线程的使用步骤,... 目录问题根源分析解决方案验证验证实验实验1:未启用keep-alive实验2:启用keep-alive扩展建

C++ 中的 if-constexpr语法和作用

《C++中的if-constexpr语法和作用》if-constexpr语法是C++17引入的新语法特性,也被称为常量if表达式或静态if(staticif),:本文主要介绍C++中的if-c... 目录1 if-constexpr 语法1.1 基本语法1.2 扩展说明1.2.1 条件表达式1.2.2 fa

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制

C++中::SHCreateDirectoryEx函数使用方法

《C++中::SHCreateDirectoryEx函数使用方法》::SHCreateDirectoryEx用于创建多级目录,类似于mkdir-p命令,本文主要介绍了C++中::SHCreateDir... 目录1. 函数原型与依赖项2. 基本使用示例示例 1:创建单层目录示例 2:创建多级目录3. 关键注

java String.join()的使用小结

《javaString.join()的使用小结》String.join()是Java8引入的一个实用方法,用于将多个字符串按照指定分隔符连接成一个字符串,本文主要介绍了javaString.join... 目录1. 方法定义2. 基本用法2.1 拼接多个字符串2.2 拼接集合中的字符串3. 使用场景和示例3

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

C++常见容器获取头元素的方法大全

《C++常见容器获取头元素的方法大全》在C++编程中,容器是存储和管理数据集合的重要工具,不同的容器提供了不同的接口来访问和操作其中的元素,获取容器的头元素(即第一个元素)是常见的操作之一,本文将详细... 目录一、std::vector二、std::list三、std::deque四、std::forwa

C++字符串提取和分割的多种方法

《C++字符串提取和分割的多种方法》在C++编程中,字符串处理是一个常见的任务,尤其是在需要从字符串中提取特定数据时,本文将详细探讨如何使用C++标准库中的工具来提取和分割字符串,并分析不同方法的适用... 目录1. 字符串提取的基本方法1.1 使用 std::istringstream 和 >> 操作符示