Skip to content

Commit 43fbde0

Browse files
committed
完成第四章“限时等待”中的“时钟”这一小节,略微修改之前内容
1 parent 412ac61 commit 43fbde0

File tree

1 file changed

+51
-1
lines changed

1 file changed

+51
-1
lines changed

md/04同步操作.md

+51-1
Original file line numberDiff line numberDiff line change
@@ -761,4 +761,54 @@ std::shared_future<std::string>sf{ p.get_future() }; // 隐式转移所有权
761761
762762
条件变量 `std::condition_variable` 的等待函数,也有两个超时的版本 [`wait_for`](https://zh.cppreference.com/w/cpp/thread/condition_variable/wait_for) 和 [`wait_until`](https://zh.cppreference.com/w/cpp/thread/condition_variable/wait_until) 。它们和我们先前讲的 `wait` 成员函数一样有两个重载,可以选择是否传递一个[*谓词*](https://zh.cppreference.com/w/cpp/named_req/Predicate)。它们相比于 `wait` 多了一个解除阻塞的可能,即:**超过指定的时长或抵达指定的时间点**。
763763
764-
在讲述它的使用细节之前,我们还是要来先聊一下 C++ 中的时间库,指定时间的方式,它较为麻烦。我们分:*时钟*、*时间段*、*时间点*三个阶段稍微介绍一下。
764+
在讲述它的使用细节之前,我们还是要来先聊一下 C++ 中的[**时间库**](https://zh.cppreference.com/w/cpp/chrono#std::chrono_.E5.BA.93)(chrono),指定时间的方式,它较为麻烦。我们分:***时钟**(clock)*、***时间段**(time point)*、***时间点**(duration)*三个阶段稍微介绍一下。
765+
766+
### 时钟
767+
768+
在 C++ 标准库中,时钟被视为时间信息的来源。C++ 定义了很多种时间类型,每种时钟类型都提供了四种不同的信息:
769+
770+
- 当前时间
771+
- 时间类型
772+
- 时钟节拍
773+
- 稳定时钟
774+
775+
当前时间可以通过静态成员函数 `now` 获取,例如,[`std::chrono::system_clock::now()`](https://zh.cppreference.com/w/cpp/chrono/system_clock/now) 会返回系统的当前时间。特定的时间点则可以通过 [`time_point`](https://zh.cppreference.com/w/cpp/chrono/time_point) 来指定。`system_clock::now()` 的返回类型就是 `time_point`。
776+
777+
时钟节拍被指定为 1/x(x 在不同硬件上有不同的值)秒,这是由时间周期所决定。假设一个时钟一秒有 25 个节拍,因此一个周期为 `std::ratio<1,25>` 。当一个时钟的时钟节拍每 2.5 秒一次,周期就可以表示为 `std::ratio<5,2>`。
778+
779+
类模板 [**`std::chrono::duration`**](https://zh.cppreference.com/w/cpp/chrono/duration) 表示时间间隔。
780+
781+
```cpp
782+
template<class Rep, class Period = std::ratio<1>>
783+
class duration;
784+
```
785+
786+
> [`std::ratio`](https://zh.cppreference.com/w/cpp/numeric/ratio/ratio) 是一个分数类模板,它有两个非类型模板参数,也就是分子与分母,分母有默认实参 1,所以 `std::ratio<1>` 等价于 `std::ratio<1,1>`
787+
788+
如你所见,它默认的时钟节拍是 1,这是一个很重要的类,标准库通过它定义了很多的时间类型,比如 **`std::chrono::minutes`** 是分钟类型,那么它的 `Period` 就是 `std::ratio<60>` ,因为一分钟等于 60 秒。
789+
790+
```cpp
791+
std::chrono::minutes std::chrono::duration</* int29 */, std::ratio<60>>
792+
```
793+
794+
稳定时钟(Steady Clock)是指提供稳定、持续递增的时间流逝信息的时钟。它的特点是不受系统时间调整或变化的影响,即使在系统休眠或时钟调整的情况下,它也能保持稳定。在 C++ 标准库中,[`std::chrono::steady_clock`](https://zh.cppreference.com/w/cpp/chrono/steady_clock) 就是一个稳定时钟。它通常用于测量时间间隔和性能计时等需要高精度和稳定性的场景。可以通过 `is_steady` 静态常量判断当前时钟是否是稳定时钟。
795+
796+
稳定时钟的主要优点在于,它可以提供相对于起始时间的稳定的递增时间,因此适用于需要保持时间顺序和不受系统时间变化影响的应用场景。相比之下,像 [`std::chrono::system_clock`](https://zh.cppreference.com/w/cpp/chrono/system_clock) 这样的系统时钟可能会受到系统时间调整或变化的影响,因此在某些情况下可能不适合对时间间隔进行精确测量。
797+
798+
不管使用哪种时钟获取时间,C++ 提供了函数,可以将时间点转换为 [**time_t**](https://zh.cppreference.com/w/cpp/chrono/c/time_t) 类型的值:
799+
800+
```cpp
801+
auto now = std::chrono::system_clock::now();
802+
time_t now_time = std::chrono::system_clock::to_time_t(now);
803+
std::cout << "Current time:\t" << std::put_time(std::localtime(&now_time), "%H:%M:%S\n");
804+
805+
auto now2 = std::chrono::steady_clock::now();
806+
now_time = std::chrono::system_clock::to_time_t(now);
807+
std::cout << "Current time:\t" << std::put_time(std::localtime(&now_time), "%H:%M:%S\n");
808+
```
809+
810+
C++ 的时间库极其繁杂,主要在于类型之多,以及实现之复杂。根据我们的描述,了解基本构成、概念、使用,即可。
811+
812+
### 时间段
813+
814+
### 时间点

0 commit comments

Comments
 (0)