并行和并发的区别?系统支持处理多个任务,就是并发;如果操作系统有多核,也即能支持同一物理时间上多个任务同时运行,则为并行。并行是并发的子集,区别在与是否多处理器。
C++14/C++17并发机制的更新?
1章 STL概论与版本简介
- STL是79年诞生,98年加入cpp标准库。C11出来之前boost库是常见的智能指针库,c11有自己的智能指针。且有多个STL版本,如SGI STL,GNU STL。
- p19-p34,用判断各种宏定义是否存在,来define一些变量,就是可以在不同的平台上,有不同的源码定义的意思。
2章 空间配置器
- STL标准是要定义std::allocator,但SGI里面常用的确是std::alloc配置器p47。
- SGI STL具有次级SGI空间配置器的能力,比如vector<int, std::alloc> iv写法。
- SGI定义了一个simple_alloc类【用alloc实现】,用于实现vector等等数据结构。
STL 主要的内存配置器
SGI定义了一个simple_alloc类【用std::alloc实现】,用于实现两层配置器。p54、p55图展现关系、
- 主配置器:在申请大内存时使用。底层用malloc和free实现。set_new_handller()函数可以定义一个在oom时的
- 次配置器:如果申请小于128的内存则用此配置器。通过维护1个free-list,list含有16个块,每个块是一个链表,链表中还有块时就用,链表中块不够时去内存池memory pool取出一个块,供调用者使用。
内存池p66:就是free-list中chunk_alloc的实现。
chunk_alloc(size_t blockSize, int& requestNumberOfBlock)
- 内存池能满足要求 requestNumberOfBlock * blockSize,就返回
- 内存池能够满足一个 requestNumberOfBlock,就返回1个快
- 1个内存快都不能满足:首先先将内存池中残余内存放入free_list合适的块中,在向heap申请内存补充内存池。
内存基本处理函数
以下3个类型,对pod类型数据会执行较快的拷贝如(copy/fill/fill_n),非pod类型执行for遍历一个一个拷贝。p76
- uninitialized_copy:对初始化的区域,用拷贝构造来生成对象
- uininitialized_fill
- uininitialized_fill_n:对[Ft, Ft+n)
3章 迭代器概念与traits编程技法
STL设计容器&算法的思想
- 容器设计者:不仅要设计容器,还要尽可能基于iterator设计容器的5个typedef p84/89。
- deque_iterator虽然没有显示继承iterator实现,但它也实现了5个typedefp140。
- 算法设计者:设计对不同读写能力迭代器的算法。STL算法的命名以其能接受的最低层次的迭代器命名,如advance(InputIterator& i, Distance n)可以接受Input、Forward、Bidirectional、Random Access四种类型的参数。
a. 总共是有input、ouput、forward、bidirectional、randomAccessIterator
b. 支持随机读写的容器:vector,deque,
c. 不支持随机读写的容器:list(底层链表)、pair(就两个元素)、map和set(红黑树或哈希表)
template<class Category, class T, class Distance=ptrdiff_t,
class Pointer=T*, class Reference=T&>
struct iterator{ // 相当于java的interface。
typedef Category iteator_category;
typedef T value_type;
typedef Distance difference_type;
typedef Pointer pointer;
typedef Reference reference;
}
// 某一个实现类应该是, 参考p100
template<class Item>
struct ListIter: public std::iterator<std::forward_iterator_tag, Item>{}
Traits获取变量类型
- iterator_traits:负责萃取迭代器的各种类型
- __type_traits:负责萃取pod相关的类型,p104
- __type_traits:负责萃取pod相关的类型,p104
template <class I>
struct iterator_traits{
typedef typename I::iterator_category iterator_category; // 帮助容器选择算法的
// func( iterator_traits<INPUT>::iterator_category()); // p99
typedef typename I::value_type value_type;
typedef typename I::difference_type difference_type;
typedef typename I::pointer pointer;
typedef typename I::reference reference;
}
如果没有反射,那怎么获取某个迭代器的类型呢?特性萃取iterator_traits。怎么获取某对象的类型呢?
type_traits。
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc> { // 有删减
typedef _Tp value_type;
typedef typename _Base::pointer pointer;
typedef typename _Alloc_traits::reference reference;
typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
}
4章 序列式容器
项目 | Value |
---|---|
电脑 | $1600 |
手机 | $12 |
导管 | $1 |
容器结构 | 结构说明说明反正大家都是用simpe_alloc分配和释放的,具体是啥得看结构。insert()、insert_aux(iter, x)、erase、operatoer[]、 |
---|---|
vector | 本质:用simple_alloc分配和释放的heap:用vector实现的堆,默认priority_queue:用vector【可以调整的】实现的优先级队列 |
list | list本质:带有哨兵的双向链表 |
deque | deque(双端队列)本质:利用复杂的map中控结构来管理,还可以随机读写的一个容器。双向开口的,所以头尾插入效率较高可随机读写的,random access关于deque的排序先赋值给vector,在用vector排序,这样效率高p143;stack本质:是用deque/list管理的先入后出的栈 queue本质:用deque/list管理的先入先出队列 |
slist | 本质:是一个只能头部插入(头插法的)单向的链表slist和list底层都是链表,其迭代器不是通过计算偏移量得到的故而不失效。比如list的insert, erase,splice,p186。slist一直头插法,insert、splice当然不失效;迭代器失效的情况:比如vector的insert会失效的。 |
5章 关联式容器
就是形如key:value的容器,比如map和set,通常以rb-tree为底层的,或者以hashtable为底层。
二分搜索树:特例有平衡的二分搜索树
- 它的特例是AVL,相差为1
- 红黑树,
项目 | Value
-------- | -----
#include | 以红黑树RB-tree为底层的容器,就是node(key+value)为节点构建的树。插入就会增加节点,删除就会减少节点,有插入删除就会有RB-Tree的旋转过程。如果允许重复键值的插入:就有multiset、multimap;如果不允许重复键值的插入:就是map、set两个而已,p198-246,就总结出这么点点的东西。 |
---|---|
#include <unordered_map> | 以hashtable为底层的容器,就是以桶和链表组成的表嘛。使用它就会有一些注意。如果一个插入操作让hashtable里元素个数>桶的个数,就会发生resize。桶的个数取值是比较固定的比如53、97、193等p257页有,每次取最接近的,且大于table元素个数的那个数。重要方法:insert_unique()方法插入唯一值,insert_equal方法插入可重复值。hash_function:很多对象不能hash,要自定义hash。自定义的类要自己写hash_funcEqualKey = eqaul_to:常见种类:hash_set、hash_map、hash_multiset、hash_multimap。 |
// #include <unordered_map>
// GCC的源码
template <class Key, class T, class Hash = hash<Key>, class Pred = equal_to<Key>,
class Alloc = allocator<pair<const Key, T>>>
class unordered_map
{
public:
// types
typedef Key key_type;
typedef T mapped_type;
typedef Hash hasher;
typedef Pred key_equal;
typedef Alloc allocator_type;
typedef pair<const key_type, mapped_type> value_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef typename allocator_traits<allocator_type>::pointer pointer;
typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
typedef typename allocator_traits<allocator_type>::size_type size_type;
typedef typename allocator_traits<allocator_type>::difference_type difference_type;
}