- 博客(130)
- 资源 (23)
- 收藏
- 关注
原创 [C++11 并发编程] 17 超时等待 - time_point
模版类std::chrono::time_point用于表示一个时间点。我们需要为时间点指定参考时钟(clock )和相对于参考时钟步进值。time point的值实际上就是某个时间点到参考时钟的起始时间(比如格林威治标准时间 1970 年 1 月 1 日的00:00:00.000)的时间长度。这个长度是时钟步进的倍数。其关键成员如下:Member typesM
2015-09-10 18:04:53
2398
1
原创 [C++11 并发编程] 17 超时等待 - clock和duration
之前我们看到的所有等待机制都是不会超时的,也就是说,等待某个同步事件的线程会一直挂起。有些情况下,我们希望设置一个最长等待时间,使得程序可以继续与用户进行交互,使得用户可以取消这个操作。我们先来看看C++11提供的时钟类clock:clockclock提供了如下四种信息:当前时间存放从clock获取到的时间的类型时钟每个tick的周期每个tick的周期是否固定,固定则为“ste
2015-09-09 14:59:32
6060
原创 [C++11 并发编程] 16 在期望中保存异常
如果在异步线程中发生了异常,等待期望的线程如何才能知道并且正确的处理异常呢?假设有如下所示的一个求平方根的函数:double square_root(double x){ if(x<0) { throw std::out_of_range(“x<0”); }return sqrt(x);}
2015-08-31 23:05:02
909
原创 [C++11 并发编程] 15 承诺promise
假设有一个应用程序应用程序用于处理大量的网络连接,通常我们会为每一个连接创建单独的处理线程。当线程数量较少时,这样是可行的,但是随着连接数量的增加,大量的线程需要消耗大量的系统资源。这样,使用较少的线程,每个线程处理多个连接更为合适。std::promise提供了一个设置值的机制(类型T),通过与之关联的期望对象可以获取到被设置的值。std::promise/std::future一起配合,等
2015-08-28 22:34:58
2690
原创 [C++11 并发编程] 14 关联任务与期望
std::packaged_task对象被触发时,它将调用关联的函数和可调用对象使得期望被满足,并将返回值填入期望关联的数据之中。这个可以用于构建线程池,也可以用于任务管理(每个任务在各自的线程中执行或所有任务顺序的在一个后台线程中执行)。如果一个大的操作可以被拆分为多个子任务,每个子任务就可以被放入一个std::packaged_task实例打交道而不是与具体的函数打交道。std::pack
2015-08-28 00:41:46
1410
原创 [C++11 并发编程] 13 使用期望等待一次性事件
C++标准库使用期望(future)来支持一次性事件的等待。要等待某种一次性事件的线程可以获取一个代表该该事件的期望。这个线程可以每隔一段事件周期性的查询这个期望。此外,这个线程也可以继续做其它的处理,直到需要等待这个一次性事件才被挂起。通过期望还可以可以传递数据。C++标准库提供了两种期望unique future(std::future),都声明在库头文件中。std::future实例只能
2015-08-27 21:02:32
2027
转载 [C++] Most Vexing Parse
这个东西可能会常见,所以还是单独写出来比较好。所谓的Most Vexing Parse是个什么东西呢。它是C++中的一个特性,这个特性表述起来其实是这样子的:凡是长得像是函数声明的,就是函数声明。是不是听的有点糊涂了?好那么我们举个几个例子好啦。我们都知道像是string这种东西,一般声明的时候,不用赋值就会调用缺省的构造函数了,对吧。所以一般我们这么些就可以了:
2015-08-27 11:54:29
2014
原创 [C++11 并发编程] 12 使用条件变量创建线程间安全的队列
之前有一节中,我们使用mutex实现了一个线程间安全的堆栈。这一节,我们使用条件变量来实现一个线程间安全的队列。标准库中的std::queuetemplate >class queue {public: explicit queue(const Container&); explicit queue(Container&& = Container()); qu
2015-08-26 21:28:01
1125
原创 [C++11 并发编程] 11 - 线程间同步 - 等待一个消息或某种条件
上一节,我们了解了如何对线程之间的共享资源进行保护的方法。但是,有些时候,我们需要在线程之间进行同步操作。一个线程等待另一个线程完成某项工作后,再继续自己的工作。比如,某个线程需要等待一个消息,或者某个条件变成true。接下来几节,我们会看到如何使用C++标准库来做到线程间同步。等待另一个线程完成的方法有如下几种:一个线程不停地查询某个被mutex保护的贡献数据区中的标志的状态。另
2015-08-26 18:05:03
12878
原创 git clone permission denied(publickey)
创建ssh密钥后,从github clone仓库到本地出现permissoin denied(publickey)错误。参考官方文档(generating-ssh-keys)的方法来添加ssh密钥到ssh-agent:连接到ssh-agent:ssh-agent -s添加私钥:ssh-add ~/.ssh/id_rsa出现Could not open a c
2015-08-25 23:16:53
4606
1
原创 [C++11 并发编程] 10 - 对极少修改的数据进行保护
假设有一个用于进行域名解析的DNS缓存数据,在大多数情况下,DNS数据很少会改变。当用户访问新的网站时,新的DNS信息才会被自动添加到这个转换表之中。虽然对这个数据的修改很少发生,但是在多个线程读取数据时,有线程要修改数据,仍然会导致读取线程读到错误的数据。我们需要使用某种方式来对读写操作进行保护。使用前面几节用到的std::mutex可以达到保护数据完整性的效果,但是效率太低。因为大多数线程
2015-08-24 23:42:04
933
原创 [C++11 并发编程] 09 - 在初始化阶段保护共享数据
除了mutex,还有一些其它的方法在特定的场景下对共享数据进行保护,首先,我们来看看如何在初始化阶段保护数据。有些时候,只需要在初始化阶段对共享数据进行保护,这样的数据可能在创建好之后是只读的,这样就没有同步问题。也可能在操作数据时,已经有了必要的保护。这样如何还是使用mutex来保护初始化过程,就没有太大必要,也比较影响性能。C++标准提供了一个纯粹用于在初始化阶段保护共享数据的机制。假
2015-08-22 17:55:45
979
原创 [C++11 并发编程] 08 - Mutex std::unique_lock
相对于std::lock_guard来说,std::unique_lock更加灵活,std::unique_lock不拥有与其关联的mutex。构造函数的第二个参数可以指定为std::defer_lock,这样表示在构造unique_lock时,传入的mutex保持unlock状态。然后通过调用std::unique_lock对象的lock()方法或者将将std::unique_lock对象传入s
2015-08-21 21:39:23
8838
原创 [C++11] 默认构造函数
类通过一个特殊的构造函数来控制默认初始化过程,这个函数就是默认构造函数,默认构造函数无需任何实参。我们可以显示的定义默认构造函数也可以让编译器为我们生成默认构造函数。默认构造函数以如下规则初始化累的数据成员:如果存在类内初始值,用它来初始化成员。否则,默认初始化该成员。class Sales_data {public: std::string bookNo; unsign
2015-08-18 09:53:10
1954
原创 [C++11 并发编程] 07 - Mutex 死锁
假设有两个线程,在执行某些操作时,都需要锁定一对mutex,线程A锁定了mutex A,而线程B锁定了额mutex B,它们都在等待对方释放另一个mutex,这就会导致这两个线程都无法继续执行。这种情况就是死锁。避免死锁最简单的方法是总是以相同的顺序对两个mutex进行锁定,比如总是在锁定mutex B之前锁定mutex A,就永远都不会死锁。假设有一个操作要交换同一个类的两个实例的内容,
2015-08-15 16:08:58
5431
原创 [C++11 并发编程] 06 - Mutex race condition
上一节中介绍了mutex的基本使用方法,使用mutex来保护共享数据并不能解决race condition带来的问题,假如我们有一个堆栈数据结构类似于std::stack它提供了5个基本操作push(),pop(),top(),empty(),和size()。这里的top()操作返回栈顶元素的拷贝,这样我们就可以使用一个mutex来保护栈内部的数据。但是race codition情况下,虽然使用m
2015-08-14 21:52:20
1393
原创 [C++11 并发编程] 05 - Mutex 基本操作
Mutex是C++中最常见的数据保护机制之一,在访问一块共享数据前,lock mutex,在完成对数据的访问后,unlock mutex。线程库当一个特定mutex被某个线程lock后,其它尝试lock同一个mutex的线程都会被挂起指导这个mutex被unlock。这就保证了所有线程看到的数据都是完整的,不会被修改了一部分的数据。在C++中,通常我们通过创建std::mutex的实例
2015-08-09 20:21:29
2416
原创 [C++11 并发编程] 04 - 动态选择并发线程的数量
C++标准模板库提供了一个辅助函数 - std::thread::hardware_concurrency(),通过这个函数,我们可以获取应用程序可以真正并发执行的线程数量。下面这个例子,实现了一个并发版本的std::accumulate,它将工作拆分到多个线程中,为了避免过多线程带来的开销,程序指定了每个线程处理数据的最小数量。头文件和求和操作:#include #include #
2015-08-08 10:53:22
2799
原创 [C++11 并发编程] 03 - 向线程传递参数
我们可以通过std::thread的构造函数向线程传递参数,但是默认情况下,这些参数的拷贝会被传递到线程内部,即使参数申明为引用,也是如此:void f(int i,std::string const& s);std::thread t(f,3,"hello");如上面例子所示,创建了一个线程关联到t,它会调用f(3, "hello"),虽然f的第二个参数类型为std::string,但是实
2015-08-07 18:10:57
7966
3
原创 [C++11 并发编程] 02 - join
1. 等待线程完成若不等待线程完成,我们就需要确保该线程访问的数据都是有效的,直到该线程完成为止。比如如下代码,线程函数持有局部变量的指针或引用,当函数退出时,线程尚未执行完成。#include #include // 线程持有局部变量的指针struct func{ int *i; func(int *i_) : i(i_){ } void operator()(
2015-08-03 21:20:28
2217
原创 [C++11]新特性试用
Auto在C++11之前,auto关键字用来指定存储期。在新标准中,它的功能变为类型推断。auto现在成了一个类型的占位符,通知编译器去根据初始化代码推断所声明变量的真实类型。各种作用域内声明变量都可以用到它。例如,名空间中,程序块中,或是for循环的初始化语句中。 auto i = 42; // i is an int auto p = new char; // p is a c
2015-07-31 08:35:38
638
原创 Git设置:
1. 创建git仓库2. $ 进入此项目所在文件夹$ git init$ git add .$ git commit -m “first commit”$ git remote add origin $ git push -u origin masterGit设置:git config --global user.name "Your Name Her
2015-07-31 08:32:50
539
原创 XCode创建C++工程
1. 创建命令行程序:2. 设置工程名和语言:3. 设置工程存储路径:4. xcode会自动为工程添加main函数:5. 编译执行:
2015-07-25 16:17:48
5569
1
原创 [C++11] thread
C++11标准库支持了thread,在MAC上试一试:#include #include void hello(void){ std::cout << "Hello concurrent world" << std::endl;}int main(void){ std::thread t(hello); t.join();}命令行编译(如果用xcode编译和其它oc工
2015-07-25 16:10:20
645
原创 [C++11] lambda表达式
可调用对象有四种:函数、函数指针、重载了函数调用运算符的类和lambda表达式。lambda表达式表示一个可调用的代码单元,可以理解为未命名的内联函数。它具有返回类型,参数列表和函数体。lambda可以定义在函数内部。其形式如下:[capture list](parameter list) -> return type { function body }capture list 捕获列表是
2015-06-05 16:35:43
741
原创 [C++]对字符串向量排序
让字符串向量首先按字符串长度进行排序,长度短的在前,长的在后。如果长度相等则按字典序排序,并移除重复的字符串。去重复并按字典序排序:void elimDumps(vector &words){ // 按字典序排序 sort(words.begin(), words.end()); // unique重排输入范围,使得每个单词只出现一次 // 并排列在范围的前部,返回指向不重复区
2015-06-04 17:50:22
3352
原创 [C++11 并发编程] 01 - Hello World
C++11标准支持了并发,其中包含了线程管理,共享资源保护,线程间同步操作和底层原子操作等功能。我们先通过一个简单的示例看看C++11标准的多线程程序是什么样的。#include #include // 引用用于管理线程的类的头文件using namespace std;// 线程的入口函数,程序将在新创建的线程中打印logvoid hello(){ cout << "Hel
2015-06-04 14:16:23
1389
原创 [C++] 使用基于范围的for循环操作string
C++11提供范围for语句,这个语句遍历给定的序列中的每个元素并对序列中的每个元素执行某种操作
2015-06-03 21:41:12
3121
原创 [C++] decltype类型指示符
有些情况下,我们希望从表达式的类型推断出要定义的变量的类型,但是不想用该表达式的值初始化变量。此时就要用到C++11引入的第二种类型说明符delctype,它的作用就是选择并返回操作数的数据类型。编译器分析表达式并得到它的类型,但不实际计算表达式的值: decltype (size(5)) s = i;' decltype返回size函数返回值的类型,来声明变量s。decltype处理
2015-05-27 08:24:49
1374
原创 [C++] auto类型说明符
我们经常会将表达式的值赋给变量,这就要求在变量声明时清楚地知道表达式的类型。有时候是很复杂的一件事,在C++11中引入了auto类型说明符,用它就能让编译器替我们去分析表达式所属的类型。当然,auto变量必须有初始值,这样编译器才能推断其类型: double val1 = 1.1, val2 = 2.2; auto item = val1 + val2; // item为double类型
2015-05-26 08:26:10
1134
原创 [C++] typedef和const
如果某个类型别名指代的是符合类型,那么把它用到声明语句中可能会让人误解。比如如下的类型pstring,实际上是char*的别名: typedef char *pstring; const pstring cstr = 0; // cstr是一个指向char的常量指针 const pstring *ps; // ps是一个指针,它的对象是指向char的常量指针上述两条声明语句的
2015-05-25 21:44:17
947
原创 [C++] constexpr和常量表达式
常量表达式是指值不会改变并且在编译时就能得到计算结果的表达式。比如字面值和用常量表达式初始化的const对象。const int max = 20;const int max_1 = max + 1;而如下对象则不是常量表达式:int staff = 5;const int sz = get_size();constexpr变量
2015-05-22 13:25:21
940
原创 [C++] cosnt指针-顶层const和底层const
指针本身是一个对象,它可以指向另一个对象。因此,指针本身是不是常量和指针所指的对象是不是常量就是两个独立的问题。顶层const表示指针本身是个常量。底层const表示指针所指的对象是个常量。下面所示,pi就是一个常量指针,不能修改pi的值。而pd则是一个指向常量的常量指针,既不能修改pd的值,也不能通过pd修改其指向对象的值。int i = 0;int *const pi = &
2015-05-22 12:59:29
1111
原创 [C++] 引用和指向指针的引用
引用,r为变量i的引用,引用类型为int: int i = 0; int &r = i; r = 100;指针的引用,r为变量p的引用,引用的是一个指针,类型为int: int i = 42; int *p; int *&r = p; r = &i; *r = 0; cout
2015-05-21 21:40:09
774
原创 [C++] 列表初始化
在C++11中,使用花括号来初始化变量得到全面的应用,也可以用花括号来对变量赋值。当用于内置类型变量时,这种初始化的一个重要特点是如果使用列表初始化且初始值存在丢失信息的风险,编译器将报错。int _tmain(int argc, _TCHAR* argv[]){ long double ld = 3.1415926536; int a{ ld }; int b = { ld };
2015-05-19 22:03:46
857
原创 [C++] 字面值的类型
字符和字符串字面值前缀含义类型uUnicode 16 字节char16_tUUnicode 32 字节char32_tL宽字符wchar_tu8UTF-8char整型字面值后缀最小匹配类型u or Uunsigned
2015-05-19 21:56:40
1228
原创 WebRTC 入门 02 通过浏览器使用摄像头 I
这一节开始,我们通过JavaScript API来开发简单的Web应用程序来学习WebRTC框架。WebRTC框架提供的API既可以用于实现简单的功能,比如一对一的视频、音频通话。也有足够的灵活性可以让有经验的开发人员实现各种复杂的功能。WebRTC为开发人员提供的API大体上可以分为三类:本地和远端音频、视频的获取和管理:MediaStreamInterface连
2015-03-25 21:36:31
3198
原创 WebRTC 入门 01 简介 III
假设Alice和Bob要使用WebRTC的呼叫功能。要实现通信,他们需要同时连接到实现了呼叫服务的web服务器。当他们打开提供呼叫服务的web页面时,他们将下载包含JavaScript的HTML页面,JavaScript通过安全的HTTP或WebSocket将浏览器连接到服务器。
2015-03-24 22:28:15
1041
原创 WebRTC 入门 01 简介 II
转载请注明出处:信令WebRTC的设计目的是解决对多媒体层的控制而不是信令层,它将信令层的东西尽量多的留给了应用层来管理。
2015-03-24 08:49:18
1084
Using Swift with Cocoa and Objective-C完整中文CocoaChina精校版
2015-02-05
iOS Programming- The Big Nerd Ranch Guide 4ed源码
2015-02-04
iOS Programming(英文第四版)- The Big Nerd Ranch Guide 4ed pdf
2015-02-02
iOS Programming(英文第四版)- The Big Nerd Ranch Guide 4ed
2015-02-02
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人