【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;
}
相关推荐
赖small强1 小时前
【Linux C/C++开发】Linux 平台 Stack Protector 机制深度解析
linux·c语言·c++·stack protector·stack-protector·金丝雀机制
Wild_Pointer.1 小时前
环境配置指南:全景目录
c++
疋瓞2 小时前
C++_win_QT6学习《3》_结合qt项目开发学习git仓库相关知识
c++·qt·学习
minji...2 小时前
Linux 基础IO(一) (C语言文件接口、系统调用文件调用接口open,write,close、文件fd)
linux·运维·服务器·网络·数据结构·c++
第二只羽毛2 小时前
C++ 高性能编程要点
大数据·开发语言·c++·算法
崇山峻岭之间3 小时前
C++ Prime Plus 学习笔记027
c++·笔记·学习
赖small强3 小时前
【Linux C/C++开发】Linux C/C++ 堆栈溢出:原理、利用与防护深度指南
linux·c语言·c++·stack·堆栈溢出
爱学习的梵高先生3 小时前
C++:基础知识
开发语言·c++·算法
oioihoii3 小时前
C++对象生命周期与析构顺序深度解析
java·开发语言·c++
xlq223223 小时前
24.map set(下)
数据结构·c++·算法