C++ 并发17 Mar 2025 | 6 分钟阅读 C++ 是一种强大而通用的编程语言。它支持广泛的编程范式,包括并发。并发是指程序中同时执行多个执行线程的能力。它能提高性能和响应能力,尤其是在涉及 I/O 密集型或 CPU 密集型任务的应用程序中。C++ 提供了内置的并发编程功能和库,例如线程、互斥锁、条件变量和 future。 1. 线程线程是一系列可以独立于主程序执行的指令。在 C++ 中,可以使用标准库中的 std::thread 类来创建线程。下面通过一个例子来理解这一点。 示例 1输出 ![]() 说明 在此示例中,通过将 "hello" 函数作为参数传递给 std::thread 构造函数来创建新线程。然后,在程序退出之前,调用线程对象的 join() 方法等待线程完成。 2. 互斥锁互斥锁是一种同步对象,可用于保护共享资源免受多个线程的并发访问。在 C++ 中,可以使用标准库中的 std::mutex 类来创建互斥锁。下面通过一个例子来理解这一点。 示例 2输出 ![]() 说明 在此示例中,使用 std::mutex 类创建了一个互斥锁。在访问共享资源(在本例中为标准输出流)之前,调用了互斥锁对象的 lock() 方法。然后,在访问完共享资源后,调用 unlock() 方法释放互斥锁。 3. 条件变量条件变量是一种同步对象,它会阻塞线程,直到满足特定条件。在 C++ 中,可以使用标准库中的 std::condition_variable 类来创建条件变量。下面通过一个例子来理解这一点。 示例 3输出 ![]() 说明 在此示例中,使用 std::condition_variable 类创建了一个条件变量。调用条件变量的 wait() 方法以阻塞线程,直到另一个线程通知它。然后,调用 notify_one() 方法通知等待的线程条件已满足。std::unique_lock<std::mutex> 用于自动锁定和解锁互斥锁对象。 4. FutureFuture 是一种同步对象,可用于从正在异步执行的线程或函数中检索值。在 C++ 中,可以使用标准库中的 std::future 类来创建 Future。下面通过一个例子来理解这一点。 示例 4输出 ![]() 说明 在此示例中,通过 std::future 类创建了一个 Future。调用 std::async() 函数来启动新线程并异步执行 hello 函数。然后,调用 Future 对象的 get() 方法以检索 hello 函数的返回值。 5. 多线程多线程是指在一个应用程序中执行多个代码线程的能力。线程是独立的执行路径,可以相互并发运行。这对于需要并行处理的应用程序很有用,例如视频编码、科学模拟或图形渲染。在 C++ 中,可以通过标准模板库 (STL) 的 thread 类来实现多线程。 多线程示例输出 ![]() 说明 在上面的示例中,使用 std::thread 类创建了两个线程,以并发执行 foo 函数。在程序退出之前,对两个线程都调用了 join() 方法以等待它们完成。 6. 并行性并行性是指使用多个线程或进程同时执行多个任务的能力。并行性对于需要高吞吐量和效率的应用程序很有用,例如数据处理、科学模拟或机器学习。在 C++ 中,可以使用 Parallel STL 库或 OpenMP 来实现并行性。 并行性示例输出 ![]() 说明 在上面的示例中,std::for_each 算法用于使用 std::execution::par 策略以并行方式将 lambda 函数应用于向量的每个元素。lambda 函数仅打印当前线程 ID 并通过将元素值加倍来处理该元素。 7. 同步同步是指协调多个线程或进程之间对共享资源(如内存或文件)的访问的过程。确保对共享资源的并发访问不会导致竞态条件或其他错误非常重要。在 C++ 中,可以使用互斥锁、条件变量或原子操作来实现同步。 同步示例输出 ![]() 说明 在上面的示例中,使用互斥锁来同步对 std::cout 对象的访问,该对象是执行 foo 函数的两个线程之间的共享资源。借助 lock() 和 unlock() 方法,我们可以获取和释放互斥锁。 8. 并发模式并发模式是并发编程中常用的设计模式,用于解决同步、通信和资源管理等常见问题。在 C++ 中,并发模式的示例包括生产者-消费者模式、读者-写者模式和监视器模式。 并发模式示例输出 ![]() 说明 在上面的示例中,使用互斥锁、条件变量和共享队列实现了简单的生产者-消费者模式。`producer` 函数生成五个整数值,并以每 500 毫秒的延迟将它们推送到队列中。每次推送后,它会使用 `notify_one()` 方法通知等待的消费者线程。`consumer` 函数使用条件变量的 `wait()` 方法等待生产者线程的通知。它以每 1000 毫秒的延迟消耗队列中的值。 最佳实践在使用 C++ 进行并发编程时,遵循最佳实践对于确保应用程序的可靠性和效率至关重要。最佳实践包括避免共享的可变状态,使用线程安全的数据结构,尽量减少对锁和同步的使用,并彻底测试代码。 结论C++ 提供了广泛的并发编程功能和库,例如线程、互斥锁、条件变量和 Future。这些功能可用于提高涉及 I/O 密集型或 CPU 密集型任务的应用程序的性能和响应能力。正确安全地使用这些功能非常重要,因为并发编程可能很复杂且容易出错。但是,通过仔细的设计和测试,C++ 可以成为强大的并发编程工具。 下一主题C++ 中的宏是什么 |
在 C++ 中编写有效可靠的代码需要仔细考虑内存管理问题。标准库提供的最有用的内存管理工具之一是 make_shared 函数。在这篇博文中,我们将探讨 make_shared 函数、它的语法以及如何...
阅读 3 分钟
Splay 树是一种二叉搜索树。它有一个独特的特性,即它们会根据最近的访问历史动态地改变其结构。这种能力使它们在某些操作方面特别有效,其中一种操作是插入节点。在本……
5 分钟阅读
在 C++ 中,typeid 运算符是一个内置运算符,允许您在运行时检索对象的类型信息。它是一个强大的工具,可用于测试、调试和编写更有效、更灵活的代码。typeid 运算符接受一个参数...
阅读 10 分钟
在 C 或 C++ 等编程语言中,我们声明任何变量,并在编译时显式声明变量的数据类型。但类型推断意味着我们使用一些关键字,通过这些关键字我们无需声明变量的数据类型...
阅读 4 分钟
unordered_multimap rehash(N) 函数在 C++ 中将容器中的元素数量增加到 n 或更多。如果 n 大于容器中的元素数量,则需要重新哈希。新元素计数可能等于或大于...
阅读 3 分钟
在本文中,我们将讨论一个用于生成长度为 n 的 Lyndon 单词的 C++ 程序。在进行实现之前,我们必须了解 Lyndon 单词。什么是 Lyndon 单词?Lyndon 单词是字符串,它们非空且具有比自身更小的词典顺序的特征...
阅读 4 分钟
用 C++ 进行编程就像踏上一场宏大的探险。在这段旅程中,你会遇到复杂的概念和令人兴奋的挑战。这篇文章中最重要的里程碑之一是掌握指针。在 C++ 中,指针就像你值得信赖的指南针,指引你穿过 intricacies...
7 分钟阅读
C++ 中强大而重要的运算符重载功能,使您能够修改用户定义数据类型的内置运算符行为。作为一种面向对象的编程语言,C++ 拥有这项主要特性。通过使您的...
11 分钟阅读
在 C++ 中添加两个数字是一项基本操作,并且是许多更复杂的算术运算的基础。它在许多方面都很重要。首先,两个数字相加是一项基本的数学运算,在日常生活中被用作……
阅读 3 分钟
在本文中,我们将讨论 C++ 中字符串的字典序排名。但在实现之前,我们必须了解字典序。字典序或字典序排序(通常称为字母顺序或字典排序)是单词按照字母顺序的组织方式……
5 分钟阅读
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India