C++并发以及多线程的秘密

server/2025/3/6 10:12:25/

1.基础概念

并发(Concurrency)

并发是指在同一时间段内,多个任务看起来像是同时执行的。并发并不一定意味着真正的同时执行,它可以是通过时间片轮转等方式在多个任务之间快速切换,让用户感觉多个任务在同时进行。并发可以通过多线程、多进程等方式实现。

线程(Thread)

线程是进程中的一个执行单元,是 CPU 调度和分派的基本单位。一个进程可以包含多个线程,这些线程共享进程的内存空间和系统资源,但每个线程有自己独立的栈空间和执行上下文。线程之间的通信和数据共享比进程更加方便和高效。比如,在一个浏览器进程中,可能会有负责渲染页面的线程、处理网络请求的线程等。

多线程(Multithreading)

多线程是实现并发的一种方式,它允许一个进程中同时存在多个线程,这些线程可以并行(在多核 CPU 上)或并发(在单核 CPU 上)执行不同的任务,从而提高程序的执行效率和响应速度。

进程(Process)

进程是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位。每个进程都有自己独立的内存空间、系统资源(如文件描述符等)和执行上下文。不同进程之间相互独立,一个进程的崩溃通常不会影响其他进程。例如,当你打开一个浏览器、一个文本编辑器时,它们分别对应着不同的进程。(一个进程有一个主线程)

2 .操作多线程

2.1 创造线程

在 C++ 中,<thread> 库提供了用于管理线程的类和函数,它是 C++11 标准引入的,用于支持多线程编程

默认构建:

std::thread t;

带执行函数的构造函数:创建一个新线程并执行指定的函数。可以传递参数给该函数

#include <iostream>
#include <thread>void func(int a) {std::cout << "线程执行,参数: " << a << std::endl;
}int main() {std::thread t(func, 42);t.join();  // 等待线程执行完毕return 0;
}

记得 线程只能出传入右值

右值引用与线程

#include <iostream>
#include <thread>
#include <string>// 线程函数,接受一个字符串参数
void threadFunction(std::string str) {std::cout << "线程接收到的字符串: " << str << std::endl;
}int main() {// 使用右值引用传递临时对象给线程std::thread t(threadFunction, std::string("Hello, Thread!"));// 等待线程执行完毕t.join();return 0;
}

左值引用与线程

左值引用用于引用一个已经存在的对象。在多线程编程中,如果需要在线程函数中修改外部对象,或者避免对象的拷贝,可以使用左值引用

#include <iostream>
#include <thread>
#include <string>// 线程函数,接受一个字符串的左值引用
void threadFunction(std::string& str) {str += " - Modified by thread";std::cout << "线程修改后的字符串: " << str << std::endl;
}int main() {std::string message = "Initial message";// 使用左值引用传递对象给线程std::thread t(threadFunction, std::ref(message));//ref提取地址// 等待线程执行完毕t.join();std::cout << "主线程看到的修改后的字符串: " << message << std::endl;return 0;
}

因为线程只能右值传递,所有以引用形式传递对象(值传递和引用之间的区别 你可以理解为复制和对地址操作)关于右值的话:c++新特性之 左右值 lambda 以及“for”-CSDN博客

成员函数

普通:

#include <iostream>
#include <thread>class MyClass {
public:// 普通成员函数void memberFunction(int value) {std::cout << "线程正在执行成员函数,传入的值是: " << value << std::endl;}
};int main() {MyClass obj;int param = 42;// 创建线程并引用类的普通成员函数std::thread t(&MyClass::memberFunction, &obj, param);// 等待线程执行完毕t.join();return 0;
}

静态:

#include <iostream>
#include <thread>class MyClass {
public:// 普通成员函数void memberFunction(int value) {std::cout << "线程正在执行成员函数,传入的值是: " << value << std::endl;}
};int main() {MyClass obj;int param = 42;// 创建线程并引用类的普通成员函数std::thread t(&MyClass::memberFunction, &obj, param);// 等待线程执行完毕t.join();return 0;
}

2.2成员函数

join函数

join() 函数的作用是阻塞当前线程,直到被调用 join() 的 std::thread 对象所代表的线程执行完毕。也就是说,当在一个线程(通常是主线程)中调用另一个线程对象的 join() 方法时,当前线程会暂停执行,等待目标线程执行结束后才会继续执行后续代码。

#include <iostream>
#include <thread>// 线程函数
void threadFunction() {for (int i = 0; i < 5; ++i) {std::cout << "子线程输出: " << i << std::endl;}
}int main() {std::thread t(threadFunction);std::cout << "主线程等待子线程执行完毕..." << std::endl;t.join();  // 主线程阻塞,等待子线程执行完毕std::cout << "子线程执行完毕,主线程继续执行。" << std::endl;return 0;
}

detch 函数

detach() 函数用于将 std::thread 对象所代表的线程与该对象分离,让线程在后台独立执行。分离后的线程在执行完毕后会自动释放资源,而不需要主线程调用 join() 来等待它结束。一旦线程被分离,就无法再通过 join() 来等待它,也不能再使用该 std::thread 对象来管理这个线程。

#include <iostream>
#include <thread>
#include <chrono>// 线程函数
void detachedThreadFunction() {std::this_thread::sleep_for(std::chrono::seconds(2));std::cout << "分离的线程执行完毕。" << std::endl;
}int main() {std::thread t(detachedThreadFunction);std::cout << "主线程不等待分离的线程,继续执行。" << std::endl;t.detach();  // 分离线程std::cout << "主线程继续执行其他任务..." << std::endl;// 主线程可以继续执行其他任务,不需要等待分离的线程return 0;
}

2.3detach陷阱

你考虑一下 上面是不是陷入陷阱?

应该是的 因为

#include <iostream>
#include <thread>
#include <chrono>// 线程函数
void detachedThreadFunction() {std::this_thread::sleep_for(std::chrono::seconds(2));//等待2s才进行std::cout << "分离的线程执行完毕。" << std::endl;
}int main() {std::thread t(detachedThreadFunction);std::cout << "主线程不等待分离的线程,继续执行。" << std::endl;t.detach();  // 分离线程std::cout << "主线程继续执行其他任务..." << std::endl;// 让主线程等待足够长的时间,确保分离的线程执行完毕std::this_thread::sleep_for(std::chrono::seconds(3)); return 0;
}

你会发现主线程已经结束了

2.4 异步执行的特性

#include <iostream>
#include <thread>
#include <chrono>
#include <vector>void threadFunction(int id) {// 模拟线程的工作负载int i=id;if (id%2==0)id=id*3;std::this_thread::sleep_for(std::chrono::seconds(id));std::cout << "Thread " << i << " finished its work." << std::endl;
}int main() {const int numThreads = 5;std::vector<std::thread> threads;// 创建多个线程for (int i = 0; i < numThreads; ++i) {threads.emplace_back(threadFunction, i + 1);}// 等待所有线程完成for (auto& thread : threads) {thread.join();}std::cout << "All threads have finished." << std::endl;return 0;
}
//就会清晰的发现 结果 
Thread 1 finished its work.
Thread 3 finished its work.
Thread 5 finished its work.
Thread 2 finished its work.
Thread 4 finished its work.

windows按工作时间来的,不是按顺序!!!


http://www.ppmy.cn/server/172841.html

相关文章

SQL经典题型

查询不在表里的数据&#xff0c;一张学生表&#xff0c;一张学生的选课表&#xff0c;要求查出没有选课的学生&#xff1f; select students.student_name from students left join course_selection on students.student_idcourse_selection.student_id where course_selecti…

如何将飞书多维表格与DeepSeek R1结合使用:效率提升的完美搭档

将飞书的多维表格与DeepSeek R1结合使用&#xff0c;就像为你的数据管理和分析之旅装上一台涡轮增压器。两者的合作&#xff0c;不仅仅在速度上让人耳目一新&#xff0c;更是将智能化分析带入了日常的工作场景。以下是它们如何相辅相成并改变我们工作方式的一些分享。 --- 在…

Linux:vim快捷键

Linux打开vim默认第一个模式是&#xff1a;命令模式&#xff01; 命令模式快捷键操作&#xff1a; gg&#xff1a;光标快速定位到最开始 shift g G&#xff1a;光标快速定位到最结尾 n shift g n G&#xff1a;光标快速定位到第n行 shift 6 ^&#xff1a;当前行开始 …

NUMA架构介绍

NUMA 架构详解 NUMA&#xff08;Non-Uniform Memory Access&#xff0c;非统一内存访问&#xff09; 是一种多处理器系统的内存设计架构&#xff0c;旨在解决多处理器系统中内存访问延迟不一致的问题。与传统的 UMA&#xff08;Uniform Memory Access&#xff0c;统一内存访问…

Android14 OTA差分包升级报Package is for source build

制作好差分包&#xff0c;使用adb线刷模式验证ota升级&#xff0c;出现E:Package is for source build错误 使用adb方式验证 进入recovery模式 adb reboot recovery稍等一会界面会提示 Now send the package you want to apply to the device with "adb sidelaod <…

蓝桥杯备考:bfs之马的遍历

像这种最短路径啊&#xff0c;我们一般都是用的bfs来求 像这道题&#xff0c;我们要定义dxdy两个方向向量 然后我们先把起点放在队列里面&#xff0c;然后把起点出队列&#xff0c;把最短路径是1的点放在队列里面&#xff0c;然后在再依次把最短路径是1的点出队列&#xff0c…

SpringMVC请求处理流程:DispatcherServlet工作原理

文章目录 引言一、DispatcherServlet概述二、DispatcherServlet初始化过程三、请求接收与处理器匹配四、请求参数绑定与处理器执行五、视图解析与渲染六、异常处理机制总结 引言 SpringMVC框架是Java Web开发中最流行的MVC框架之一&#xff0c;其核心组件DispatcherServlet作为…

【封闭式】论文写作技巧--集中学习+集中写作

学术论文写作是许多科研人员、研究生以及青年学者都会面临的重要挑战。从选题的确定到创新点的挖掘&#xff0c;再到最终成稿&#xff0c;每一步都需要逻辑清晰、方法科学和语言精准。然而&#xff0c;繁重的科研任务和有限的指导资源让许多人在论文写作过程中感到迷茫。为了解…