函数式编程:是一种编程风格,函数调用的结果仅单纯依赖于该函数的参数而不依赖于任何外部状态。意味着如果用同一个参数执行一个函数两次,结果是完全一样的。函数的影响完全局限在返回值上。
当涉及并发时,许多涉及共享内存相关的问题便不复存在。如果没有修改共享数据,那么就不会有竞争条件,因此也就没有必要使用互斥元来保护共享数据。
future是使得C++ FP风格的并发切实可行,一个future可以再线程间来回传递,使得一个线程的计算结果依赖于另一个结果,而无需任何对共享数据的显示访问。简言之:每个任务都可以提供他所需要的数据,并通过使用future将结果传播至需要它的线程。
// 快速排序的顺序实现
template <typename T>
std::list<T> quick_sort(std::list<T> input)
{
if (input.empty()) // 判断输出list是否为空
return input;
std::list<T> result;
result.splice(result.begin(), input, input.begin()); // 取第一个数,放入result,并将其从input删除
const T &pivot = *result.begin();// 常量左值引用,避免复制 // 基准数
// 按照基准数进行划分
auto divide_point = std::partition(input.begin(), input.end(), [&](T const &t) -> bool { return t < pivot; });
std::list<T> lower_part;
lower_part.splice(lower_part.begin(), input, input.begin(), divide_point);
//递归
auto new_lower = quick_sort(std::move(lower_part)); // 对前半部分进行划分
auto new_higher = quick_sort(std::move(input)); // 对后半部分进行划分
result.splice(result.end(), new_higher);
result.splice(result.begin(), new_lower);
return result;
}
// 快速排序的并行实现
template <typename T>
std::list<T> quick_sort_con(std::list<T> input)
{
if (input.empty())
return input;
std::list<T> result;
result.splice(result.begin(), input, input.begin());
const T &pivot = *result.begin();
auto divide_point = std::partition(input.begin(), input.end(), [&](T const &t) -> bool { return t < pivot; });
std::list<T> lower_part;
lower_part.splice(lower_part.begin(), input, input.begin(), divide_point);
// 每次递归,新开一个线程对较小的部分进行排序。
std::future<std::list<T>> new_lower(std::async(&quick_sort_con<T>, std::move(lower_part)));
// 较大的部分仍然在当前线程进行排序
auto new_higher(quick_sort_con(std::move(input)));
// 顺序拼接
result.splice(result.end(), new_higher);
result.splice(result.begin(), new_lower.get());
return result;
}