C++线程编程-FP编程和CSP编程

news/2024/7/2 20:21:33

FP

/**
 * 使用操作同步来简化代码 - 带有future的函数式编程(FP)
 * 
 * 才有函数式的方法来编写程序,并非直接在线程之间共享数据;
 * 而是每个任务都可以提供它所需要的数据,并通过使用future将结果传播至需要它的线程
 * 
 * future是使得C++FP风格的并发切实可行的最后一块拼图;
 * 一个future可以在线程之间来回传递,使得一个线程的计算结果以来于另一个的结果,而无需任何对共享数据的显示访问。
 * 
 * 这个风格的快速排序是用list,因为list的splice方法
 * 如果用vector,估计要用算法库里面的算法,而且性能可能不是很高;
 * 因为splice是直接移动的指针,不需要拷贝,这是链表的优势所在
 */

#include <list>
#include <iostream>
#include <algorithm>
#include <future>
using namespace std;

// 1.FP风格快速排序
template<typename T>
list<T> sequential_quick_sort(list<T> input)
{
    if(input.empty())
    {
        return input;
    }
    list<T> result;
    // 将input中的input.begin()这个元素转移到result.begin()的位置
    // 不是复制或移动元素,而是重指向链表节点的内部指针,原指针实效,被移除
    // 所以可以把solice勉强的看成是可移动的
    result.splice(result.begin(),input,input.begin());
    // 使用引用,避免复制,中轴值
    const T &pivot = *result.begin();
    // 将序列划分成小于中轴值的和不小于中轴值的,返回第一个不小于中轴值的迭代起
    auto divide_point = partition(input.begin(),input.end(),[&](const T &t){
        return t < pivot;
    });
    // 新建一个存放小于的容器,大于等于的可以存放在原容器
    list<T> lower_part;
    // 将序列小于中轴值的部分转移到lower_part列表
    // 这样lower_part全是小于中轴值的元素,input还剩下大于等于中轴值的元素
    lower_part.splice(lower_part.end(),input,input.begin(),divide_point);
    // 使用递归分别对小于中轴值的序列进行同样的操作,使用移动,防止拷贝
    auto new_lower(sequential_quick_sort(move(lower_part)));
    // 使用递归对大于等于中轴值的序列进行同样的操作,使用移动,防止拷贝
    auto new_higher(sequential_quick_sort(move(input)));
    // 最后将结果进行正确的拼接,把大于等于的部分拼接到中轴值的后面
    result.splice(result.end(),new_higher);
    // 把小于的部分,拼接到中轴值的前面
    result.splice(result.begin(),new_lower);
    // 返回最终结果
    return result;
}

// FP风格并行快速排序
template<typename T>
list<T> parallel_quick_sort(list<T> input)
{
    if(input.empty())
    {
        return input;
    }
    list<T> result;
    result.splice(result.begin(),input,input.begin());
    const T &pivot = *result.begin();
    auto divide_point = partition(input.begin(),input.end(),[&](const T &t){
        return t<pivot;
    });
    list<T> lower_part;
    lower_part.splice(lower_part.begin(),input,input.begin(),divide_point);
    // 这种并发是否有用?前面的结果总是要等后面的结果才可以返回;
    // 结果和结果之间是需要等待的,但是两部分是可以同时进行的,所以并发还是有一定的作用。
    future<list<T>> new_lower(async(&parallel_quick_sort<T>,move(lower_part)));
    future<list<T>> new_higher(async(&parallel_quick_sort<T>,move(input)));
    // auto new_higher(parallel_quick_sort(move(input)));
    result.splice(result.end(),new_higher.get());
    result.splice(result.begin(),new_lower.get());
    return result;
}

int main()
{
    list<int> t{2,34,4,1,5,63,3,24,5,6};
    //list<int> value = sequential_quick_sort(t);
    list<int> value = parallel_quick_sort(t);
    for (auto &&i : value)
    {
        cout << i << " ";
    }
    cout << endl;
    exit(0);
}

CSP

  • CSP基于消息传递的同步操作
  • CSP的思想很简单,如果没有共享数据,则每一个线程可以完全独立的运行;
  • 只需要基于它对所接收到的信息如果进行反映
  • 由于线程天生就是共享全局数据的,所以程序员必须保证:
  • 不会在线程之间共享数据,只在线程之间共享消息队列,
  • 既然要有这种封装性,就可以封装成类
  • 很可能会使用状态机的思想
  • 不同的角色对应不同的线程,成为角色模型

http://www.niftyadmin.cn/n/3459259.html

相关文章

冲刺2-1

团队开会总结上一阶段的失败之处&#xff0c; 也把第二阶段要完成的任务分配 大屏的空教室展示&#xff0c;课表的录入 转载于:https://www.cnblogs.com/1983185414xpl/p/11066618.html

入侵检测 - AIDE高级入侵检测平台

2019独角兽企业重金招聘Python工程师标准>>> AIDE(Advanced Intrusion Detection Environment)是一款针对文件和目录进行完整性对比检查的程序&#xff0c;它被开发成Tripwire的一个替代品。 AIDE如何工作 这款工具年纪也不小了&#xff0c;相对来同类工具Tripwire说…

C++线程编程-内存顺序

内存顺序模型 有六种内存顺序选项可以应用到原子类型上&#xff0c; memory_order_relaxed;memory_order_consume; memory_order_acquire;memory_order_release;memory_order_acq_rel; memory_order_seq_cst; 它们代表三种模型&#xff1a; 顺序一致 memory_order_seq_cst;获…

看源码,我为什么推荐IDEA?

1.条件断点 看源码的时候,经常遇到这个情况,源码中有个for循环,关键是这个list的size有时候长达数百个.但是我们只想debug一种情况.肥朝就曾经见过,在for循环中打了断点,一直按跳过,按了数十下之后.才找到自己想debug的值.这样效率不高 比如下文这个 1Test2public void testLis…

SQLServer中SYSCOLUMNS表的各个字段的意义

列名 数据类型 描述 name sysname 列名或过程参数的名称。 id int 该列所属的表对象 ID&#xff0c;或与该参数关联的存储过程 ID。 xtype tinyint systypes 中的物理存储类型。 typestat tinyint 仅限内部使用。 xusertype smallint 扩展的用户定义…

C++线程编程-设计基于锁的并发数据结构

序列化 多个线程轮流存取互斥元保护的数据&#xff0c;它们必须线性的而非并发的存取数据。 高并发就意味着&#xff1a;更小的保护区域&#xff0c;更少的序列化&#xff0c;更高的并发潜能。 设计基于锁的并发数据结构关键是要确保存取数据时要锁住正确的互斥元&#xff0c…

SQLServer常用系统存储过程

sp_add_log_file_recover_suspect_lib 当数据库的复原不能完成时,向文件组增加一个日志文件sp_add_targetservergroup 增家指定的服务器组sp_add_targetsvrgrp_member 在指定的目标服务器组增加一个目标服务器sp_addapprole 在数据库里增加一个特殊的应用程…

深入理解Java中的底层阻塞原理及实现

Information Technology Solutions as a Presentation 谈到阻塞&#xff0c;相信大家都不会陌生了。阻塞的应用场景真的多得不要不要的&#xff0c;比如 生产-消费模式&#xff0c;限流统计等等。什么 ArrayBlockingQueue、 LinkedBlockingQueue、DelayQueue 等等&#xff0c;都…