【2】c++多线程技术之多线程标准库的使用

1、线程的构造与启动

在C++中,多线程有关的头文件为<thread>,我们可以使用std::thread类来创建和管理线程。下面是一个简单的示例代码:

cpp 复制代码
#include <iostream>
#include <thread>  // 包含线程库相关头文件
void thread_function() {
    std::cout << "Hello from the new thread!" << std::endl;
}
int main() {
    // 创建一个新线程并执行函数 thread_function
    std::thread t(thread_function);
    // 等待线程执行完成
    t.join();
    return 0;
}

在这个示例中,我们首先包含了头文件,以便我们可以使用std::thread类。然后,我们定义了一个名为print_hello的函数,这个函数将在新线程中执行。在main函数中,我们创建了一个名为t的新线程,并将print_hello函数作为参数传递给它。这将导致print_hello函数在新线程中执行。最后,我们调用了t.join()方法来等待线程完成。这是一个阻塞调用,意味着主线程将等待新线程完成后再继续执行。如果不调用join()方法,新线程将成为分离状态,这意味着当主线程结束时,新线程可能会继续运行。

2、线程的终止与析构

线程的终止和析构主要涉及到两个概念:线程的结束和线程对象的销毁。
线程的结束 :当线程的任务函数返回时,线程就会自动结束。如果需要在主线程中结束一个子线程,可以使用std::thread类的join()或detach()方法。join()方法会阻塞当前线程,直到被调用join()的线程结束。detach()方法则会将子线程设置为后台运行,主线程不会等待其结束。
线程对象的销毁:当一个std::thread对象被销毁时,如果该对象关联的线程仍在运行,程序会调用std::terminate()函数,导致程序异常终止。因此,需要确保在销毁std::thread对象之前,已经正确地结束了线程。

cpp 复制代码
#include <iostream>
#include <thread>
void thread_task() {
    for (int i = 0; i < 5; ++i) {
        std::cout << "Thread task running: " << i << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}
int main() {
    // 创建一个线程对象t,关联到thread_task函数
    std::thread t(thread_task);
    // 等待线程t结束
    t.join();
    // 销毁线程对象t
    // 如果线程t还在运行,程序会调用std::terminate()函数,导致程序异常终止
    // 所以在实际使用中,需要确保在销毁std::thread对象之前,已经正确地结束了线程
    return 0;
}

3、std::thread::joinstd::thread::detach

std::thread::join:这个方法会阻塞当前线程,直到被调用的线程执行完毕。如果一个线程已经被join或者detach,再次调用这两个方法会导致程序终止。
std::thread::detach:这个方法将线程设置为"分离"状态,这意味着主线程不会等待这个线程结束。一旦线程结束,系统会自动回收其资源。
std::thread::join代码示例

cpp 复制代码
#include <iostream>
#include <thread>
void threadFunction() {
    std::cout << "Hello from thread!\n";
}
int main() {
    // 创建一个新线程
    std::thread t(threadFunction);
    // 使用join方法等待线程结束
    t.join();
    // 输出消息表示主线程继续执行
    std::cout << "Hello from main!\n";
    return 0;
}

std::thread::detach方法代码示例

cpp 复制代码
#include <iostream>
#include <thread>

void threadFunction() {
    std::cout << "Hello from thread!\n";
}

int main() {
    // 创建一个新线程
    std::thread t(threadFunction);

    // 使用detach方法使线程在后台运行
    t.detach();

    // 输出消息表示主线程继续执行
    std::cout << "Hello from main!\n";

    return 0;
}

4、std::this_thread与当前线程操作

std::this_thread是C++标准库中的一个命名空间,它提供了一些与当前线程操作相关的函数和类。通过使用std::this_thread,我们可以获取当前线程的ID、设置线程名称、休眠线程等。下面是一个简单的示例代码,演示了如何使用std::this_thread来获取当前线程的ID和设置线程名称

cpp 复制代码
#include <iostream>
#include <thread>
#include <chrono>
void threadFunction() {
    // 获取当前线程的ID
    std::thread::id thisThreadId = std::this_thread::get_id();
    std::cout << "Current thread ID: " << thisThreadId << std::endl;
    // 设置当前线程的名称
    std::this_thread::sleep_for(std::chrono::seconds(1)); // 休眠1秒,确保线程名称设置成功
    std::this_thread::set_name("MyThread");
    // 再次获取当前线程的ID
    thisThreadId = std::this_thread::get_id();
    std::cout << "Current thread ID after setting name: " << thisThreadId << std::endl;
}
int main() {
    // 创建一个新线程并执行threadFunction函数
    std::thread myThread(threadFunction);
    // 等待新线程执行完毕
    myThread.join();
    return 0;
}
相关推荐
草莓熊Lotso32 分钟前
Linux 文件描述符与重定向实战:从原理到 minishell 实现
android·linux·运维·服务器·数据库·c++·人工智能
历程里程碑35 分钟前
Linux22 文件系统
linux·运维·c语言·开发语言·数据结构·c++·算法
在路上看风景8 小时前
19. 成员初始化列表和初始化对象
c++
zmzb01038 小时前
C++课后习题训练记录Day98
开发语言·c++
念风零壹9 小时前
C++ 内存避坑指南:如何用移动语义和智能指针解决“深拷贝”与“内存泄漏”
c++
孞㐑¥9 小时前
算法——BFS
开发语言·c++·经验分享·笔记·算法
MZ_ZXD00111 小时前
springboot旅游信息管理系统-计算机毕业设计源码21675
java·c++·vue.js·spring boot·python·django·php
A星空12312 小时前
一、Linux嵌入式的I2C驱动开发
linux·c++·驱动开发·i2c
凡人叶枫12 小时前
C++中智能指针详解(Linux实战版)| 彻底解决内存泄漏,新手也能吃透
java·linux·c语言·开发语言·c++·嵌入式开发
会叫的恐龙12 小时前
C++ 核心知识点汇总(第六日)(字符串)
c++·算法·字符串