多线程编程学习笔记(一)

前言

个人想了解这块内容,文章中所提及的,来源于 chatGPT, 若后面了解的过程中发现其所表述有误的话,再做修正吧。

多线程的基本概念

在计算机中,线程是进程中的一个执行单元。一个程序可以由多个线程组成,线程间共享程序的资源(例如内存),但每个线程有自己的执行路径。通常,会创建多个线程并发执行不同的任务,从而实现并行计算。

线程的基本结构:

• 进程:一个运行中的程序,每个进程有自己的地址空间、资源等。

• 线程:进程中的最小执行单元,每个线程有自己的栈空间,多个线程共享进程的资源(例如内存、文件描述符等)。

创建线程

C++11引入了对多线程的支持,提供了库来方便地创建和管理线程。

#include <iostream>
#include <thread>

// 一个简单的函数,将被线程执行
void hello() {
std::cout << "Hello from thread!" << std::endl;
}

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

解释:

• std::thread t(hello);:创建一个线程t,并让它执行hello函数。

• t.join();: join()方法用于等待线程执行完毕。如果没有调用join()或detach(),程序可能会在主线程结束时直接退出,导致子线程未执行完毕。

线程同步与共享数据

多个线程同时访问共享数据时,会发生数据竞争,即多个线程同时修改数据,导致不一致的结果。因此,需要使用同步机制来避免这种情况。

使用mutex进行同步

C++提供了std::mutex来保证同一时刻只有一个线程能够访问共享资源。

#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx; // 定义一个互斥锁
int shared_data = 0;

void increment() {
std::lock_guard<std::mutex> lock(mtx); // 自动加锁,作用域结束后自动解锁
++shared_data; // 访问共享数据
}

int main() {
std::thread t1(increment);
std::thread t2(increment);

t1.join();
t2.join();

std::cout << "Shared data: " << shared_data << std::endl; // 应该输出 2
return 0;
}

线程的常见操作

detach

detach(): 将线程与主线程分离,主线程退出时,分离线程将继续执行。

std::thread t(hello);
t.detach(); // 线程将独立执行,不需要等待

线程的返回值

可以让线程返回结果,可以通过std::future和std::promise实现。

#include <iostream>
#include <thread>
#include <future>

int add(int a, int b) {
return a + b;
}

int main() {
std::future<int> result = std::async(std::launch::async, add, 3, 4);
std::cout << "Result: " << result.get() << std::endl; // 输出 7
return 0;
}

std::async(): 异步启动一个线程来执行add函数,并返回一个std::future对象,稍后可以通过result.get()获取返回值。

总结

• 创建线程:使用std::thread类。

• 线程同步:使用std::mutex来保护共享资源。

• 线程间通信:使用std::future和std::promise来实现线程之间的通信和获取返回值。

• 线程生命周期管理:使用join()等待线程结束,detach()让线程与主线程分离。

参考

[1] chatGPT

知识共享许可协议