- 博客(33)
- 资源 (138)
- 收藏
- 关注
原创 C++模板实战5: 迭代器与容器
一份带有迭代器的双向链表实现:#include#include_Pragma ("once")template class List;templateclass Iterator{ public: using value_type=typename N::value_type; using reference_type=typename N::
2013-12-31 09:38:08 1310
原创 C++模板实战4:模板特化
模板设计的目的就是为了通用,但是某些情形下也有特殊情形独立于通用规则,因此模板需要针对特殊情形进行特化。1 类模板的特化,在模板类名自后这部分叫做匹配式,如下:template//通用模板void show();template不能省略void show();//特化模板,其中叫匹配式特化规则如下: 1) 匹配式写在模板类名之后,用也不能省略 2) 匹配式内用逗号隔开
2013-12-30 13:17:11 1913
原创 C++模板实战3:模板参数
模板参数可以是class,也可以是:整数及枚举类型、指向对象或函数的指针、对象或函数的引用、对象成员的指针。 1 整数模板参数,但是必须是编译期常量,实例如下:#include#includeusing namespace std;templateclass array{//具备越界检查的数组 public: T& operator[](unsig
2013-12-29 21:14:48 1597
原创 C++模板实战2:模板类
1 借助函数模板可以使算法脱于具体数据类型之外,借助模板类可以使数据结构脱于具体数据类型之外,从而专注于数据存取方法及数据间的关联方式,抽象的数据结构可以和具体数据类型无关。类模板和函数模板一样以template开头,但是类模板实例化和函数模板实例化有一点不太一样,函数模板可以从函数参数自动推导模板参数从而可以省略模板参数的书写,而类模板即使有默认模板参数其 one;其中采用默认模板
2013-12-29 17:10:07 1976
原创 C++模板实战1:函数模板
模板本身不是可编译的代码,而是用来指导编译器生成可编译代码的文本。1 函数模板参数 函数模板参数可以根据模板实参自动推导,也就是说可以从实参自动推导的模板参数可以省略书写,但是要注意以下几个规则:1) 编译器只根据函数调用时给出的实参列表推导模板参数值,与函数参数无关的模板参数无法推导2) 与函数返回值相关的模板参数其值也无法推导3) 所有可推导模板参数必须是连续位于
2013-12-28 11:02:54 1662
原创 Ubuntu安装graphviz
1 sudo apt-get install graphviz2 编写一个test.dot的文件,内容如下:digraph abc{ a; b; c; d; a->b; b->d; c->d;}3 编译文件: dot -Tsvg test.dot -o test.svg,在当前目录下生成一个图文件test.svg,如下所示:
2013-12-27 16:16:13 12311
原创 C++11: nullptr、默认函数的控制、lambda函数、对齐方式
1 nullptr nullptr是nullptr_t类型的实例化,替代了传统的NULL,C++11的指针空值常量。 nullptr_t是指针空值类型,nullptr仅仅是nullptr_t的一个实例,nullptr_t的使用规则:1) 所有定义为nullptr_t类型的数据都是等价的,行为也完全一致2) nullptr_t类型数据可以隐式转换成任意一个指针
2013-12-26 21:19:48 2453 1
原创 C++并发实战19:lock free编程
涉及到并行/并发计算时,通常都会想到加锁,加锁可以保护共享的数据,不过也会存在一些问题:1. 由于临界区无法并发运行,进入临界区就需要等待,加锁使得效率的降低。多核CPU也不能发挥全部马力2. 在复杂的情况下,很容易造成死锁,并发进程、线程之间无止境的互相等待。3. 在中断/信号处理函数中不能加锁,给并发处理带来困难。4. 加锁影响实时性,等待时间不确定5. 优先级反转,优先级
2013-12-26 12:50:44 5630
原创 C++并发实战18: 线程安全的查找表和链表
经常遇见根据关键字查找内容的应用如DNS查询,标准库的std::map系列可供选择,但是它们是非线程安全的,一个线程安全的查找表实现如下,其主要是通过hash函数将各个key分散到具体的bucket中去,每个bucket带有一个共享锁boost::shared_mutex,从而实现线程安全的高并发数据结构:#include #include #include #include #inc
2013-12-25 14:22:16 7495
原创 C++11:提高性能及操作硬件的能力
1 constexpr编译时期常量 constexpr用于函数:constexpr int get(){return 10};int array[get()];//get()返回一个编译期常量可以用于声明数组大小constexpr int a=get();//a是一个编译期常量int b=get();//此时get当一个普通函数使用,b不再是常量常量表达式函数必须满足:1
2013-12-24 21:56:29 3113
原创 C++并发实战17:线程安全的stack和queue
1 线程安全的数据结构有几个可以注意的地方:当一个线程看见invariants时其他线程不会破坏该invariants,比如一个线程在遍历访问vector另一个线程却在修改vector这就破坏了variants;注意数据结构接口引起的竞态,必要的时候将多个操作合并;注意异常的处理;避免局部操作的锁超出其作用范围,否则可能引起死锁;尽可能的缩小临界区。 线程安全的栈关键代码:#in
2013-12-24 16:59:31 7244 1
原创 C++11:提高类型安全
1 强类型枚举 C98的enum是非强类型作用域(在一个子命名空间定义的enum其父空间也可加enum成员,即enum相当于全局的,容易引起重复值),允许隐式类型转换(这条规则可以允许不同enum类型间相互比较成员值),占用存储空间及符号性不确定。C++11引入了强类型枚举enum class/struct具有以下特点:强作用域,子空间的枚举成员不会输出到父空间中; 转换限制,枚
2013-12-22 21:53:40 1584
原创 C++11: 新手易学,老兵易用
1 C++11中针对vector >两个尖括号间的空格去除,也就是说C++11中可以写成:vector>,编译器这里不会将>>认为是右移符号。2 auto: C++中每个变量使用前必须定义从而被视为静态语言,而不像一些脚本语言变量可以这样用x=1称为动态语言。 静态语言和动态语言主要区别:静态语言类型检查发生在编译阶段,动态语言类型检查发生在运行阶段。C++11中实现了auto和de
2013-12-21 23:13:07 2173 2
原创 C++11:通用为本,专用为末
1 派生类可以自动获得基类的成员变量和接口(虚函数、纯虚函数),但是基类的非虚函数则无法被再被派生类使用了,所以派生类要使用基类的构造函数也需要显示声明,当基类的构造函数有多个版本的时候就需要在派生类中透传许多基类的构造函数。在C++11中派生类要使用基类的成员函数的话可以通过using声明完成。struct A { A(int i) {} A(double d, in
2013-12-21 11:08:44 2078
原创 C++并发实战16: std::atomic原子操作
针对原子类型操作要不一步完成,要么不做,防止由于多线程串行化带来的错误。1 std::atomic_flag是一个bool原子类型,其支持test_and_set和clear两个操作,atomic_flag内部维护一个状态flag。atomic_flag::test_and_set检查flag是否被设置,若被设置直接返回true,若没有设置则设置flag为true后再返回false。atom
2013-12-19 15:50:03 95061 7
原创 C++并发实战15:函数式编程
函数y=f(x)就是个x->y的映射,其仅仅是x和y的关系,其运算关系仅仅是依赖参数x并不涉及其它外部状态。在函数式编程中,每个语句是一个表达式都是执行单纯的计算并有返回值,而C中的语句是执行某种操作如赋值,且计算是由函数完成的,仅仅依赖于输入参数。如一条简单的函数语句,功能是(1+2)*3-4:var result = subtract (multiply (add (1,2), 3), 4
2013-12-18 15:33:07 4474
原创 C++并发实战14:时间
std::chrono::system_clock::now()//返回系统当前时间 时钟周期:std::ratio //表示1s内25个周期 std::chrono::system_clock::is_steady() //测试系统时钟周期是否可调 std::chrono::duration > //时间间隔,第一个参数short(或long,doubl
2013-12-17 14:42:30 3886
原创 C++并发实战13:std::future、std::async、std::promise、std::packaged_task
std::condition_variable可以用于异步事件的重复通知,但是有些时候可能只等待事件发生一次,比如:等待特定的航班,用条件变量大杀器有点浪费了。C++11标准库提供了几种异步任务机制。通常thread不能返回线程执行的结果(可以通过引用参数返回),而在异步处理当中很多时候都需要获得计算的结果。如果只获取结果一次那么选用future,即通过future获取了结果后,后续再通过此fut
2013-12-16 20:05:26 18644 2
原创 C++11:兼容性
1 C++11保持与C99兼容 1.1 用于跨平台的相关宏 __STDC_HOSTED__完整包含C库为1否则为0 ; __STDC__是否和c标准一致 ; __STDC__VERSION__ 所支持的c标准版本 ; __STDC_ISO_10646 编译环境是否符合某个版本的C++标准 ; 通过以上宏程序员通过#ifdef/#endif预处理实现跨平台 1.2 __fun
2013-12-14 20:32:36 3405
原创 C++并发实战12:线程安全的queue
1 首先看下STL中的queue的接口:template >class queue { public: explicit queue(const Container&); explicit queue(Container&& = Container()); template explicit queue(const Alloc&); template
2013-12-13 15:16:30 21843 11
原创 C++并发实战11:条件变量
1 线程睡眠函数std::this_thread::sleep_for(std::chrono::milliseconds(100));//头文件#include,供选择的如seconds()等 不要使用睡眠函数同步线程,睡眠函数可以用于复现线程的一些行为。2 条件变量std::condition_variable不允许拷贝和移动的。其基本语义和Linux的pthr
2013-12-13 12:45:59 5706
原创 C++并发实战10:保护共享数据的可选机制
使用mutex的时候要尽量缩小临界区,若可能的话,对mutex加锁仅仅是为了获取共享数据,而对数据的计算放在临界区之外。a lock should be held for only the minimum possible time needed to perform the required operations。一个非常好的实例就是copy on write。不要在临界区内进行IO,IO比内存
2013-12-12 11:39:36 3371
原创 C++并发实战9:unique_lock
1 回顾采用RAII手法管理mutex的std::lock_guard其功能是在对象构造时将mutex加锁,析构时对mutex解锁,这样一个栈对象保证了在异常情形下mutex可以在lock_guard对象析构被解锁。explicit lock_guard (mutex_type& m);//必须要传递一个mutex作为构造参数lock_guard (mutex_type& m, adopt_
2013-12-11 16:36:31 18553 3
原创 C++并发实战8:deadlock
1 死锁:每个线程都希望锁住一些列锁以执行某个操作,且每个线程持有一个不同的锁,最终每个线程都需要其它线程的锁,导致所有线程都不能向前执行。 1.1 顺序加锁lock 1.1 死锁的一个解决方式:每个线程对锁的请求顺序一致。C++库提供了顺序加锁机制,可以一次性锁住多个mutex而不会出现死锁:void lock (Mutex1
2013-12-11 14:15:23 3633 2
原创 C++并发实战7:thread::mutex
创建一个互斥量std::mutex; mutex::lock(),mutex::unlock()互斥量的加锁解锁,try_lock未加锁时加锁否则不加锁返回false。但是不建议直接使用lock和unlock,因为这样需要在各种情形下保证lock和unlock的匹配,即使是抛出异常。标准库中采用RAII手法封装了mutex的类std::lock_guard在构造时lock,析构时unlock。lo
2013-12-10 10:51:32 4262 1
原创 C++并发实战6:thread::id
线程标识符id可以通过thread::get_id()获得,若thread obejct没有和任何线程关联则返回一个NULL的std::thread::id表示没有任何线程。当前线程若想获得自己的id可以调用std::this_thread::get_id()。 thread::id对象可以被任意复制和比较。这里的比较语义是:若相等表示是同一个线程或者都没有线程,不等表示不同的
2013-12-04 17:37:07 4513
原创 C++并发实战5:并行化的std::accumulate
std::thread::hardware_concurrency()可以返回CPU个数,在C++库不能获取CPU信息下可能返回0。该信息是非常有用的,当线程数超过CPU cores会频繁的引起上下文切换,返回会降低性能,当hardware_concurrency()返回0时可以指定一个数目比如2。 下面给出一个并行化的std::accumulate()的例子:std::ac
2013-12-04 16:46:21 4569 3
原创 C++并发实战4:thread object is movable,not copyable
假设这样一个情形:假设函数A创建一个thread object返回给A的调用者,或者A将thread obejct转移给其它函数。thread object is movable but no copyable like std::unique_ptr or std::ifstream可以看出thread object是可以转移其所有权的。void some_function();void
2013-12-03 17:56:57 3036 1
原创 Ubuntu安装g++-4.8
sudo add-apt-repository ppa:ubuntu-toolchain-r/testsudo apt-get updatesudo apt-get install g++-4.8至此,g++-4.8已经安装,但还未被设为默认。再执行下面的命令切换链接。sudo rm /usr/bin/g++sudo ln -s /usr/bin/g++-4.8 /usr/bin
2013-12-03 16:44:43 5791
原创 C++并发实战3:向thread传递参数
在创建thread object时可以向线程传递参数,默认情况下,参数会被拷贝到线程空间以供线程执行时存取,即使参数是引用也是这样。情形1:void f(int i,std::string const& s); boost::thread t(f,3,”hello”); //字符串常量“hello”会被转换为string,该string在线程中存在。
2013-12-03 15:01:49 19176 5
原创 C++并发实战2:thread::join和thread::detach
thread::join()是个简单暴力的方法,主线程等待子进程期间什么都不能做,一般情形是主线程创建thread object后做自己的工作而不是简单停留在join上。thread::join()还会清理子线程相关的内存空间,此后thread object将不再和这个子线程相关了,即thread object不再joinable了,所以join对于一个子线程来说只可以被调用一次,为了实现更精细的
2013-12-02 14:11:29 36651 2
原创 Ubuntu笔记:系统使用,程序调试报错等
1 查看环境 env |grep -i HADOOP_CMD ,添加环境在/etc/environment
2013-12-01 23:47:39 2177
原创 关于muduo网络库的注解
注:muduo用C++实现蛮有意思的,其大量使用boost的shared_ptr,bind,function实现对象生命期控制、事件回调机制,且基于对象编程而非面向对象编程。在此记点笔记吧,以备后查。文字部分:1 Reactor模式的实现:关键是三个类:Channel,Poller,EventLoop。 class Channel:事件分发器,其记录了描述符fd的注册事
2013-12-01 23:29:47 4082 2
一个最容易懂的 LaTeX 入门教材.pdf
2013-08-13
ggplot2 -- Elegant Graphics for Data Analysis.PDF
2013-07-13
MySQL技术内幕Innodb存储引擎.xmind
2020-07-11
Desinging Data-Intensive Applications-2.xmind
2020-07-11
Desinging Data-Intensive Applications.xmind
2020-07-11
Machine Learning-A Probabilistic Perspective.pdf
2013-09-09
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人