等待未来事件
现实世界中的需求
- 未来事件;(这是我瞎诌的一个概念),在未来某个时间点发生;并且只会发生一次;而且发生时可能会携带数据, 也可能不会.
- 在编程中经常会碰到,一个线程需要等待未来事件发生后才能继续执行;或者多个线程等待同一个未来事件发生.
C++ future,shared_future 设施
future<T>
,shared_future<T>
的区别;就类似unique_ptr
,shared_ptr
之间的区别;即future<T>
对象是仅有与未来事件关联的实例,即不可与其他future<T>
实例共享同一未来事件;而shared_future<T>
对象可以,可以多个实例共享着同一未来事件;future<T>
,shared_future<T>
中的T
表示未来事件关联数据的类型.若为void
,则表明future<T>
,shared_future<T>
关联的未来事件没有数据.future<T>
,shared_future<T>
对象是非线程安全的;即不能多个线程访问同一个数据对象.
创建 future 对象
async
async()
创建的未来事件在其关联的函数执行完成后发生;并且此时未来事件的数据就是函数的返回值.
package_task
-
package_task<F>
与std::function<T>
一致,其内保存着一个可执行对象,并且本身也是一个可执 行对象;模板参数F
指定了其调用形式;如:/* 从 package_task 的定义可以看出; * o F 的参数列表指定了 package_task 的调用形式. * o F 的返回值类型指定了 package_task 关联 future 的模板参数; */ struct package_task<int (int,int)> { void operator(int,int); std::future<int> get_future(); };
-
当调用
package_task<F>
对象时,会执行其内保存的函数对象,当其内保存的函数对象执行完成后,package_task<F>
关联的future<T>
对象变为就绪状态.并且将返回值存放到future<T>
中. -
此时
package_task<F>
创建的未来事件在package_task<F>
对象被调用时发生;关联的数据就是package_task<F>
内保存的函数对象的返回值.
promise
promise<T>
/future<T>
就像管道的写,读端;此时promise<T>
创建的未来事件在调用promise<T>::set_value()
时发生,并且此时未来事件关联的数据就是set_value()
的参数.
将异常保存在 future 对象中
- 若
async()
在异步执行函数过程时发生了异常,则会将异常对象保存到关联的future<T>
上. - 若
package_task<F>
在执行时发生了异常,则会将异常对象保存到关联的future<T>
对象上.若package_task<F>
在被析构时仍未被执行,则也会将特定的异常对象保存到关联的future<T>
对象上. - 通过调用
promise<T>::set_exception()
显式将异常对象保存到future<T>
之上;若promise<T>
对象在 被析构时仍未调用过set_value()
或set_exception()
,则也会将一个特定的异常对象保存到关联的future<T>
对象上.
创建 shared_future
- 创建
future
对象,然后将该对象移动(future
无法拷贝,只能移动)给shared_future
对象. -
通过调用
future<T>::share()
函数得到shared_future
对象.如:auto sf = future<T>::share(); // 此时可以使用'auto'关键词省事.
有时间限制的等待
超时的指定
- 相对时间;
- 绝对时间;
- 在 c++ 中,接受相对时间作为超时参数的函数一般以’_for’结尾.接受绝对时间作为超时参数的函数一般以 ‘_util’结尾.
C++ 时钟类
- 在 C++ 中,时钟作为一个类存在,提供如下信息:
- 时钟的当前值(当前时间);通过
CLOCK::now()
函数获取. - 时钟表示时间的类型;即:
CLOCK::time_point
-
时钟的节拍周期;即时钟走一拍所需要的时间;即:
CLOCK::period
;如:typedef std::ratio<5,2> period; // 这表明时钟在 5 秒内走 2 拍.即节拍周期为 2.5 秒.
- 若时钟的节拍周期不固定;则
period
可能被定义为平均值,或者开发者认为合适的值.
- 若时钟的节拍周期不固定;则
- 是否是匀速时钟;通过
CLOCK::is_steady()
确定;- 匀速时钟;以均匀的速率计时,并且不可被调整.
TODO
- 4.3 节未看.
并发编程范式
FP;函数式编程
- 纯函数;即函数的调用结果仅依赖函数的参数,不依赖任何外部状态;同时函数的调用结果仅作用在函数的返回 值上,不影响任何外部状态.
CSP;通信顺序处理
- 其特点就是:线程之间完全独立;没有共享数据;但是具有可以传递消息的通信通道.
转载请注明出处!谢谢