1. 并发(Concurrency)
并发是指系统处理多个任务的能力,这些任务看起来是同时进行的,但实际上可能是交替执行的。
关键特点:
- 任务间的切换可能发生在任何时刻
- 适用于I/O绑定的任务
- 可以在单核处理器上实现
- 主要目标是提高程序的响应性和资源利用率
C++代码示例:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex cout_mutex;
void print_message(const std::string& message) {
for (int i = 0; i < 5; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
std::lock_guard<std::mutex> lock(cout_mutex);
std::cout << message << " " << i << std::endl;
}
}
int main() {
std::thread t1(print_message, "Thread 1");
std::thread t2(print_message, "Thread 2");
t1.join();
t2.join();
return 0;
}
这个例子创建了两个线程,它们并发执行相同的函数。虽然它们看起来是同时运行的,但在单核系统上,它们实际上是交替执行的。
2. 并行(Parallelism)
并行是指同时执行多个任务,通常在多核处理器或多台机器上实现。
关键特点:
- 任务真正同时执行
- 适用于CPU密集型任务
- 需要多核处理器或分布式系统
- 主要目标是提高处理速度和吞吐量
C++代码示例:
#include <iostream>
#include <vector>
#include <algorithm>
#include <execution>
#include <chrono>
void parallel_sum(const std::vector<int>& vec) {
auto start = std::chrono::high_resolution_clock::now();
long long sum = std::reduce(std::execution::par, vec.begin(), vec.end(), 0LL);
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> duration = end - start;
std::cout << "Parallel sum: " << sum << std::endl;
std::cout << "Time taken: " << duration.count() << " ms" << std::endl;
}
void sequential_sum(const std::vector<int>& vec) {
auto start = std::chrono::high_resolution_clock::now();
long long sum = std::accumulate(vec.begin(), vec.end(), 0LL);
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> duration = end - start;
std::cout << "Sequential sum: " << sum << std::endl;
std::cout << "Time taken: " << duration.count() << " ms" << std::endl;
}
int main() {
std::vector<int> numbers(100000000, 1); // 1亿个1
std::cout << "Parallel execution:" << std::endl;
parallel_sum(numbers);
std::cout << "\nSequential execution:" << std::endl;
sequential_sum(numbers);
return 0;
}
这个例子展示了并行算法和顺序算法在计算大量数字之和时的性能差异。并行版本利用多核处理器同时处理数据的不同部分。
并发与并行的比较
-
执行方式:
- 并发:任务可能交替执行
- 并行:任务同时执行
-
资源要求:
- 并发:可以在单核处理器上实现
- 并行:需要多核处理器或多台机器
-
适用场景:
- 并发:适合I/O绑定任务,如网络通信、文件操作
- 并行:适合CPU密集型任务,如大规模数据处理、科学计算
-
主要目标:
- 并发:提高程序响应性和资源利用率
- 并行:提高处理速度和吞吐量
-
实现复杂度:
- 并发:需要处理同步、互斥等问题,实现较复杂
- 并行:需要考虑任务分解和负载均衡,但同步问题相对较少
结论
理解并发和并行的区别对于设计高效的多任务程序至关重要。并发适合处理需要频繁I/O操作或等待的任务,而并行则更适合处理可以被分解为独立子任务的计算密集型问题。在实际应用中,我们常常需要结合使用这两种技术来最大化程序的性能和效率。
通过合理利用C++提供的并发和并行工具,开发者可以充分发挥现代硬件的潜力,创造出更快、更高效的应用程序。