修正上篇的high_resolution_clock的描述
一。chrono部分
chrono::duration的代码实现
template <class _Rep, class _Period>
class duration { // represents a time duration
public:
using rep = _Rep;
using period = typename _Period::type;
_Rep
参数表示传入的 时间单位 的类型,可以为float, int, long long等等,比如传入表示0.3倍个某个时间单位。_Period
参数代表了 时间单位,可以为微秒,毫秒,秒,分钟,小时 甚至是其它自定义的单位。
比如:
using d10_seconds = chrono::duration<float, std::ratio<1, 10>>; //1/10秒的时间单位,类型是float
stl库的stedy_clock代码
struct steady_clock { // wraps QueryPerformanceCounter
using rep = long long;
using period = nano;
using duration = nanoseconds;
using time_point = _CHRONO time_point<steady_clock>;
static constexpr bool is_steady = true;
_NODISCARD static time_point now() noexcept { // get current time
const long long _Freq = _Query_perf_frequency(); // doesn't change after system boot
const long long _Ctr = _Query_perf_counter();
static_assert(period::num == 1, "This assumes period::num == 1.");
// Instead of just having "(_Ctr * period::den) / _Freq",
// the algorithm below prevents overflow when _Ctr is sufficiently large.
// It assumes that _Freq * period::den does not overflow, which is currently true for nano period.
// It is not realistic for _Ctr to accumulate to large values from zero with this assumption,
// but the initial value of _Ctr could be large.
const long long _Whole = (_Ctr / _Freq) * period::den;
const long long _Part = (_Ctr % _Freq) * period::den / _Freq;
return time_point(duration(_Whole + _Part));
}
};
using high_resolution_clock = steady_clock;
#if _HAS_CXX20
// [time.duration.io]
....
high_resolution_clock可以安全使用,就是个别名而已。
(修正上篇的high_resolution_clock的描述)
学习std::ratio、chrono::duration、chrono::duration_cast以及
time_point、system_clock、steady_clock等的示范代码:
#include <ratio>
#include <algorithm>
#include <numeric>
static void slow_motion()
{
static int a[]{ 1,2,3,4,5,6,7,8,9,10,11,12 };
{
}
}
void pre_chrono()
{
{
using p1 = std::ratio<1, 100>;
using p2 = std::ratio<1, 10>;
using p = std::ratio_add<p1, p2>;
cout << "ratio " << p::num << "/" << p::den << "\n";
}
//duration, duration_cast
{
//一下三种写法,效果相同,睡眠100ms.
std::this_thread::sleep_for(std::chrono::milliseconds(100));
// or milli即为ratio<1, 1000>千分之一默认单位。(默认单位为秒)
std::this_thread::sleep_for(std::chrono::duration<long long, std::milli>(100));
// or
std::this_thread::sleep_for(std::chrono::duration<long long, std::ratio<1, 1000> >(100));
//仿造std::milli写法,可构造个新单位,比如:3/10秒
using second_3_10 = chrono::duration<long long, std::ratio<3, 10>>; //使用long long 是与chrono::seconds配合一致。
chrono::seconds val = chrono::duration_cast< chrono::seconds >(second_3_10(4));
cout << "4个3/10秒val = " << val.count() << " 个秒\n";
using three_seconds = chrono::duration<float, std::ratio<3, 1> > ;
using one_tenth_seconds = chrono::duration<float, std::ratio<1, 10> > ;
three_seconds s = chrono::duration_cast<three_seconds>(one_tenth_seconds(3));
cout << "3个1/10秒val = " << s.count() << " 个3秒\n";
using seven_seconds = chrono::duration<float, std::ratio<7, 1>>; //7秒的单位
using d10_seconds = chrono::duration<float, std::ratio<1, 10>>; //1/10的单位
d10_seconds s1 = chrono::duration_cast<d10_seconds>(seven_seconds(2));
d10_seconds s2 = chrono::duration_cast<d10_seconds>(seven_seconds(0.33));
d10_seconds s3 = s1 + s2;
s3 ++;
cout << "2个七秒 == " << s1.count() << " 个1/10秒。 0.33个七秒 == " << s2.count() << " 个1/10秒\n";
cout << "sum = " << s3.count() << "\n";
int kk = 0;
using n2_d5 = chrono::duration<float, std::ratio<2, 5>>; //宏定义个2/5秒的单位。接下来看看一个2/5秒等于多少个毫秒
using n1_d1000 = chrono::duration<float, ratio<1, 1000>>;
n1_d1000 t1 = chrono::duration_cast<n1_d1000>(n2_d5(1));
n1_d1000 t2 = chrono::duration_cast<n1_d1000>(n2_d5(3));
cout << "一个2/5秒 == " << t1.count() << "\n";
cout << "三个2/5秒 == " << t2.count() << "\n";
kk = 0;
}
//time_point
//system_clock, steady_clock, high_resolution_clock
{
vector<double> val(100'000'000, 0.4);
auto t_start = chrono::steady_clock::now(); //time_point
double val_sum = std::accumulate(val.begin(), val.end(), 1.0);
auto t_end = chrono::high_resolution_clock::now();
chrono::duration<double, std::ratio<1, 1000>> msec = t_end - t_start;
chrono::duration<double, std::ratio<1, 10>> d10sec = t_end - t_start;
cout << "耗时:" << msec.count() << " 毫秒\n";
cout << "耗时:" << d10sec.count() << " 个1/10秒\n";
}
chrono::time_point<chrono::system_clock, chrono::seconds> tp(chrono::seconds(120)); //120s
int tick_seconds = tp.time_since_epoch().count();
cout << "从纪元开始过了(epoch) " << tick_seconds << "s\n";
time_t tt = chrono::system_clock::to_time_t(tp);
char szbuff[64];
ctime_s(szbuff, sizeof(szbuff), &tt);
cout << szbuff << "\n";
}
二。条件变量学习的代码示范
10个消费者,一个生产者的代码
/// <summary>
/// C.以下是10个消费者线程,一个生产者线程
/// </summary>
int cargo_2 = 0;
const int CNT = 10;
struct is_judge2_ext {
int m_i = 0;
is_judge2_ext(int iv) :m_i(iv) {};
bool operator()() {
return cargo_2 == m_i;
}
};
std::once_flag of_flag;
void consume3(int iIdx)
{
std::call_once(of_flag, [&]() {
cout << "only once!" << iIdx << "\n";
});
for (int i = 0; i < 3; i++) {
std::unique_lock<std::mutex> lck(mtx2);
{
if (i) {
std::cout << "wait " << iIdx << std::endl;
}
_cond2.wait(lck, is_judge2_ext(iIdx));
}
cout << "consume " << iIdx << endl;
cargo_2 = 0;
}
}
//#define MULTI_PRODUCE
void test_cond3() //接口,同时也作为生产者
{
std::thread _thd[CNT];
for (int i = 0; i < CNT; i++) {
_thd[i] = std::thread(consume3, i + 1);
}
#ifdef MULTI_PRODUCE
#else
for (int j = 0; j < 3; j++) {
for (int i = 0; i < CNT; i++) {
int times = 0;
while (cargo_2) {
std::this_thread::yield();
times++;
}
{
std::unique_lock<std::mutex> lck(mtx2);
cargo_2 = CNT - i;
std::cout << "produce " << cargo_2 << " " << times << std::endl;
}
//条件变量通知无须持有锁的!!!
_cond2.notify_all();
}
cout << "prod over!\n\n";
}
#endif
for (auto& _iter: _thd) {
_iter.join();
}
int k = 0;
}