16 多线程编程之线程基本概念

在前面一篇中,我们概述了C++中的异常处理机制,并深入探讨了如何设计异常安全的代码。在本篇中,我们将转向多线程编程,首先了解线程的基本概念。线程是程序执行的基本单元,通过对线程的掌握,我们可以更好地应对并发编程带来的挑战。

线程的基本概念

在操作系统中,线程进程中的一个执行单元,每个进程可以拥有多个线程。线程共享进程的资源如内存、文件描述符等,但每个线程都有自己的栈和寄存器。由于线程共享资源,因此进行多线程编程时,保证线程安全是一个重要的任务。

线程的创建

在C++中,使用std::thread类来创建和管理线程。以下是一个简单的示例,展示如何创建和运行一个线程:

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <thread>

void hello() {
std::cout << "Hello from thread!" << std::endl;
}

int main() {
std::thread t(hello); // 创建并启动线程
t.join(); // 等待线程完成
return 0;
}

在这个示例中,我们定义了一个简单的函数hello,它将在新线程中执行。我们使用std::thread创建一个线程并传入函数,然后通过join方法等待线程完成。

线程的状态

线程的状态可以分为以下几种:

  1. 可运行(Runnable):线程可以被运行,但不一定正在运行。
  2. 运行(Running):线程正在执行代码。
  3. 阻塞(Blocked):线程在等待某个事件(例如等待I/O操作完成)。
  4. 死亡(Dead):线程执行完成或被终止。

示例:线程的基本状态

下面的代码展示了如何在不同状态之间切换:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <thread>
#include <chrono>

void task() {
std::cout << "Task started" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(3)); // 模拟长时间运行的任务
std::cout << "Task completed" << std::endl;
}

int main() {
std::cout << "Creating thread..." << std::endl;
std::thread t(task);

if (t.joinable()) {
std::cout << "Thread is joinable" << std::endl;
}

t.join(); // 等待任务完成
std::cout << "Thread joined" << std::endl;

return 0;
}

在这个示例中,线程开始执行时会进入可运行状态,随后由于sleep_for函数,它会进入阻塞状态,直到任务完成并返回到主线程。

线程的生命周期

线程的生命周期主要包括以下几个阶段:

  1. 创建:通过std::thread类创建时,线程处于可运行状态。
  2. 运行:一旦得到CPU时间片,它会转为运行状态。
  3. 阻塞:在等待某个操作完成时,如I/O操作。
  4. 死亡:当线程的执行代码完成,线程进入死亡状态。此时,资源会被回收。

结论

在本篇中,我们多侧面探讨了C++线程的基本概念,包括线程的创建、状态以及生命周期的变化。这些知识是我们进一步深入多线程编程的基础,为后续讲解互斥量条件变量等内容打下了良好的基础。

在下篇中,我们将深入如何使用互斥量条件变量来管理线程之间的共享资源,确保线程安全,防止竞争条件的发生。富有挑战性的并发编程正等待着我们去探索,相信这些技术会帮助我们写出更健壮的程序。

16 多线程编程之线程基本概念

https://zglg.work/c-plusplus-one/16/

作者

IT教程网(郭震)

发布于

2024-08-10

更新于

2024-08-22

许可协议

分享转发

交流

更多教程加公众号

更多教程加公众号

加入星球获取PDF

加入星球获取PDF

打卡评论